Site Characteristics

site_temps = full_data %>% 
  dplyr::select(site, lat, season, doy, collection_temp, collection_salinity) %>%  
  distinct() %>% 
  filter(doy > 100) 

Copepods were collected by surface tow from sites across the Western Atlantic at several times throughout the year. The sites are shown below. Temperatures at the time of collection were measured using a manual thermometer. Across the entire set of collections, temperature ranged from 10°C to 36°C.

coords = site_data %>%
  dplyr::select(site, long, lat) %>%
  distinct()

site_map = map_data("world") %>% 
  filter(region %in% c("USA", "Canada")) %>% 
  ggplot() + 
  geom_polygon(aes(x = long, y = lat, group = group),
               fill = "lightgrey") + 
  coord_map(xlim = c(-85,-60),
            ylim = c(25, 48)) + 
  geom_point(data = coords,
             mapping = aes(x = long, y = lat, colour = site),
             size = 3) +
  scale_colour_manual(values = site_cols) + 
  labs(x = "Longitude", 
       y = "Latitude") + 
  theme_matt(base_size = 16)

site_temp_plot = ggplot(site_temps, aes(x = doy, y = collection_temp, colour = site)) + 
  geom_line(linewidth = 2) + 
  geom_point(size = 5) +
  scale_colour_manual(values = site_cols) + 
  labs(y = "Temperature (°C)",
       x = "Day of the Year") +
  theme_matt() + 
  theme(legend.position = "right")

ggarrange(site_map, site_temp_plot, common.legend = T, legend = "bottom")

Collections aimed to obtain copepods near the onset of peak temperatures, after peak temperatures, and then at low temperatures. Regional data is not available for all sites, so here we’ve pieced together daily temperature values from either local temperature sensors (sites in Florida and the Chesapeake) and high resolution satellite temperature data (Connecticut, Maine, and the Canadian sites). This satellite data comes from the NOAA 1/4° Daily Optimum Interpolation Sea Surface Temperature (OISST).

These temperature profiles are shown below, with the temperatures measured during the time of collection included for comparison In several cases collection temperature does not match the recorded daily averages, but the temperature records do give a general sense of the timing of seasonal maxima. In general, the first sample from each site fell just after the site reached the warmest period. The exception to that pattern is in Florida, where collections occurred after an extended period of high temperatures.

temp_profiles = temp_profiles %>% 
  filter(doy > 100) %>% 
  mutate(region = fct_relevel(region, "Florida", "Chesapeake", "Connecticut",
                              "Maine", "Shediac", "Miramichi"))

site_temps2 = site_temps %>% 
  mutate(region = case_when(
    site == "Manatee River" ~ "Florida",
    site == "Ft. Hamer" ~ "Florida",
    site == "Tyler Cove" ~ "Chesapeake",
    site == "Ganey's Wharf" ~ "Chesapeake",
    site == "Esker Point" ~ "Connecticut",
    site == "Sawyer Park" ~ "Maine",
    site == "St. Thomas de Kent Wharf" ~ "Shediac",
    site == "Ritchie Wharf" ~ "Miramichi"),
    region = fct_relevel(region, "Florida", "Chesapeake", "Connecticut",
                         "Maine", "Shediac", "Miramichi"))

ggplot(temp_profiles, aes(x = doy, y = temp_c)) + 
  facet_wrap(region~.) + 
  geom_point(data = site_temps2,
             aes(x = doy, y = collection_temp, colour = site),
             size = 3) +
  geom_line() + 
  scale_colour_manual(values = site_cols) + 
  labs(x = "Day of the Year", 
       y = "Mean Daily Temp. (°C)") + 
  theme_matt_facets() + 
  theme(legend.position = "none", 
        axis.text.x = element_text(angle = 320, hjust = 0, vjust = 0.5))

Exact locations for the sites are provided here.

site_data %>%  
  arrange(lat) %>%  
  select("Site" = site, "Region" = region, "Lat" = lat, "Long" = long) %>% 
  knitr::kable(align = "c")
Site Region Lat Long
Key Largo Florida 25.28391 -80.33014
Manatee River Florida 27.50561 -82.57277
Ft. Hamer Florida 27.52488 -82.43101
Tyler Cove Maryland 38.35083 -76.22902
Ganey’s Wharf Maryland 38.80555 -75.90906
Esker Point Connecticut 41.32081 -72.00166
Sawyer Park Maine 43.90698 -69.87179
St. Thomas de Kent Wharf New Brunswick 46.44761 -64.63692
Ritchie Wharf New Brunswick 47.00481 -65.56291

Nested within each of the three regions (South, Central, and Northern regions) are pairs of low and high salinity sites:

data.frame("Region" = c("South", "Central", "North"),
           "Low Salinity" = c("Ft. Hamer", "Ganey's Wharf", "Ritchie Wharf"),
           "High Salinity" = c("Manatee River", "Tyler Cove", "St. Thomas de Kent Wharf")) %>% 
  knitr::kable(align = "c")
Region Low.Salinity High.Salinity
South Ft. Hamer Manatee River
Central Ganey’s Wharf Tyler Cove
North Ritchie Wharf St. Thomas de Kent Wharf

 

There are fairly well-established divergences between high salinity and low salinity populations of Acartia tonsa. These sets of geographically proximate but isolated populations provide independent comparisons of the effects of seasonality. Shown here are the collection conditions for these pairs of sites. Temperature was typically similar across the pairs within each collection, while salinity differences were fairly stable across collections.

season_cols = c("early" = "grey75", 
                "peak" = "grey50", 
                "late" = "grey25")

sal_regions = data.frame(region = rep(c("South", "Central", "North"), each = 2), 
                         site = c("Ft. Hamer", "Manatee River", 
                                  "Ganey's Wharf", "Tyler Cove", 
                                  "Ritchie Wharf", "St. Thomas de Kent Wharf"),
                         salinity = c("low", "high"))

sal_comps = full_data %>% 
  filter(site %in% sal_regions$site) %>% 
  inner_join(sal_regions, by = c("site")) %>% 
  select( region = region.y, site, salinity, season, doy, collection_temp, collection_salinity,
          size, ctmax, warming_tol) %>% 
  mutate(salinity = fct_relevel(salinity, "low", "high"),
         region = fct_relevel(region, "South", "Central", "North"))

sal_comp_temps = sal_comps %>%  
  select(salinity, season, region, collection_temp, collection_salinity) %>% 
  distinct() %>% 
  ggplot(aes(x = salinity, y = collection_temp, colour = season, group = season)) + 
  facet_wrap(region~.) + 
  geom_line(linewidth = 1.5) + 
  geom_point(size = 4) + 
  scale_colour_manual(values = season_cols) + 
  labs(y = "Collection Temp. (°C)",
       x = "") + 
  theme_matt_facets(base_size = 14)

sal_comp_sal = sal_comps %>%  
  select(salinity, season, region, collection_temp, collection_salinity) %>% 
  distinct() %>% 
  ggplot(aes(x = salinity, y = collection_salinity, colour = season, group = season)) + 
  facet_wrap(region~.) + 
  geom_line(linewidth = 1.5) + 
  geom_point(size = 4) + 
  scale_colour_manual(values = season_cols) + 
  labs(y = "Collection Salinity (psu)",
       x = "Salinity") + 
  theme_matt_facets(base_size = 14)

ggarrange(sal_comp_temps, sal_comp_sal, nrow = 2, common.legend = T, legend = "right")

The latitudinal gradient covers a wide range of seasonality. Shown below is the temperature range. While based on collection temperatures, and therefore an underestimate of the total seasonal range of temperatures, these patterns are representative of the expected latitudinal gradient in seasonality.

site_temps %>% 
  group_by(site, lat) %>%  
  summarise(temp_range = max(collection_temp) - min(collection_temp)) %>%  
  ggplot(aes(x = lat, y = temp_range)) + 
  geom_point(aes(colour = site),
             size = 3) + 
  scale_color_manual(values = site_cols) + 
  labs(x = "Latitude", 
       y = "Collection Temp. Range (°C)") + 
  theme_matt() + 
  theme(legend.position = "right")

Phenotypic Measurements

Critical Thermal Limits

A total of 456 individuals were examined. Critical thermal limits and body size measurements were made before individuals were preserved in ethanol. We excluded data for 7 individuals, detailed below. These individuals had either very low CTmax or were, upon re-examination of photographs, identified as juveniles instead of mature females. With these individuals excluded, the full data set contains 449 phenotyped individuals.

excluded %>% 
  select(region, site, season, collection_temp, collection_salinity, replicate, tube, ctmax, size) %>% 
  knitr::kable(align = "c")
region site season collection_temp collection_salinity replicate tube ctmax size
Florida Manatee River peak 34.0 29 2 6 38.45833 0.616
Florida Manatee River peak 34.0 29 2 7 38.23750 0.593
Florida Ft. Hamer late 20.0 18 2 3 36.59280 0.619
Maryland Tyler Cove peak 29.5 15 2 2 36.84375 0.614
Connecticut Esker Point early 22.5 30 2 3 30.02604 0.687
Maine Sawyer Park peak 22.0 30 1 4 30.81424 0.865
New Brunswick St. Thomas de Kent Wharf late 13.5 28 1 3 28.78299 1.039

Critical thermal maxima (CTmax) was measured using a custom setup. The method uses a standard dynamic ramping assay to determine the maximum temperature individuals could sustain normal functioning. This differs from lethal temperatures, and indeed, all individuals observed so far recovered following the assay.

Individuals were rested for one hour after collection before the assay. During the assay, copepods were held in artificial seawater, composed of bottled spring water and Instant Ocean salt mix adjusted to match collection salinities. During the assay, several ‘control’ individuals were maintained in this solution at ambient temperatures without the temperature ramp to ensure that there was no background mortality. When sorting individuals from the plankton tow contents, they were held in a 50:50 mix of 60 um filtered water from the collection site and artificial seawater as an additional acclimation step.

Sample sizes varied slightly across experiments, but most sites had 20 individuals measured per season. The major exceptions were the early samples from the Florida sites and the late sample from Sawyer Park (Maine). Only two sets of samples (peak and late) were collected from Fort Hamer and Manatee River. No samples were collected from Key Largo for this project, as Acartia tonsa wasn’t present in the water during the peak season, likely due to the recent extreme heat event. The late season collection from Sawyer Park occurred after Acartia tonsa abundance decreased. Samples from this period were dominated by Acartia hudsonica instead.

ggplot(full_data, aes(x = site, fill = site)) + 
  facet_wrap(season~.) + 
  geom_hline(yintercept = c(0,20),
             colour = "grey70") + 
  geom_bar() + 
  scale_fill_manual(values = site_cols) + 
  coord_flip() +
  theme_matt() + 
  theme(legend.position = "none",
        panel.border = element_rect(linewidth = 1,
                                    fill = NA),
        strip.text = element_text(size = 20),
        axis.title.y = element_blank())

Shown below are the measured CTmax values. Note: CTmax values for the early season Key Largo copepods were collected at the end of February 2023 as part of a separate project. Body size values were not measured during this project, nor were copepods individually preserved after the experiments. These early season CTmax values are included as a point of comparison. Individual measurements are shown in small points for each collection. The large points indicate the mean values for each collection.

mean_ctmax = full_data %>% 
  group_by(site, season, doy, collection_temp) %>% 
  summarize(mean_ctmax = mean(ctmax),
            median_ctmax = median(ctmax))

ctmax_plot = ggplot(full_data, aes(x = season, y = ctmax, colour = site)) + 
  geom_line(data = mean_ctmax, 
            aes(y = mean_ctmax, group = site),
            position = position_dodge(width = 0.4),
            linewidth = 1) + 
  geom_point(position = position_jitterdodge(jitter.width = 0.1, jitter.height = 0,
                                             dodge.width = 0.4),
             alpha = 0.3) + 
  geom_point(data = mean_ctmax, 
             aes(y = mean_ctmax),
             position = position_dodge(width = 0.4),
             size = 4) + 
  scale_colour_manual(values = site_cols) + 
  labs(y = "CTmax (°C)",
       x = "Season") +
  theme_matt() + 
  theme(legend.position = "right", 
        legend.title.align = 0.125)

ctmax_plot

Warming tolerance

Warming tolerance (the difference between thermal limits and environmental temperatures) is a commonly used metric of climate vulnerability. We calculated this as the difference between measured CTmax values and the collection temperature. Smaller warming tolerance values indicate that populations were nearer to their upper thermal limits, and may therefore be more vulnerable to additional warming.

mean_wt = full_data %>% 
  group_by(site, season) %>% 
  summarize(mean_wt = mean(warming_tol),
            median_wt = median(warming_tol))

ggplot(full_data, aes(x = season, y = warming_tol, colour = site)) + 
  geom_line(data = mean_wt, 
            aes(y = mean_wt, group = site),
            position = position_dodge(width = 0.4),
            linewidth = 1) + 
  geom_point(position = position_jitterdodge(jitter.width = 0.1, jitter.height = 0,
                                             dodge.width = 0.4),
             alpha = 0.3) + 
  geom_point(data = mean_wt, 
             aes(y = mean_wt),
             position = position_dodge(width = 0.4),
             size = 4) + 
  scale_colour_manual(values = site_cols) + 
  labs(y = "Warming Tolerance (°C)",
       x = "Season") +
  theme_matt() + 
  theme(legend.position = "right", 
        legend.title.align = 0.125)

Body Size

Following the CTmax assay, individuals were photographed for body size measurements. Prosome lengths were measured from these photographs using a scale micrometer and the software ImageJ. These measurements are shown below. As before, large points indicate the mean body size. While less cohesive than CTmax, a general trend of increasing body size with latitude and time of year can be seen.

mean_size = full_data %>% 
  group_by(site, season, doy, collection_temp) %>% 
  summarize(mean_size = mean(size),
            median_size = median(size))

ggplot(full_data, aes(x = season, y = size, colour = site)) + 
  geom_line(data = mean_size, 
            aes(y = mean_size, group = site),
            position = position_dodge(width = 0.4),
            linewidth = 1) + 
  geom_point(position = position_jitterdodge(jitter.width = 0.1, jitter.height = 0,
                                             dodge.width = 0.4),
             alpha = 0.3) + 
  geom_point(data = mean_size, 
             aes(y = mean_size),
             position = position_dodge(width = 0.4),
             size = 4) + 
  scale_colour_manual(values = site_cols) + 
  labs(y = "Prosome Length (mm)",
       x = "Season") +
  theme_matt() + 
  theme(legend.position = "right", 
        legend.title.align = 0.125)

Salinity Pair Comparisons

The three pairs of cross-salinity comparisons do show evidence for fine-scale trait divergence, although there was no consistent pattern in the direction or magnitude of differences. CTmax was similar across sites in the Southern and Central pairs. In the Northern pair, CTmax tended to be slightly lower for individuals from the low salinity site. Size was more variable between the paired sites. In the South, low salinity individuals were consistently smaller than high salinity individuals, despite experiencing similar temperatures. In the Central pair, individuals from the low salinity site tended to be slightly larger than those from the high salinity site, although this varied seasonally. Sizes tended to be more similar across the collections from the Northern pair.

sal_comp_ctmax_plot = sal_comps %>% 
  ggplot(aes(x = salinity, y = ctmax, colour = season, group = season)) + 
  facet_wrap(region~.) + 
  geom_point(size = 2,
             position = position_dodge(width = 0.2)) + 
  #geom_line(size = 1.5) + 
  scale_colour_manual(values = season_cols) + 
  labs(y = "CTmax (°C)",
       x = "") + 
  theme_matt_facets(base_size = 14)

sal_comp_size_plot = sal_comps %>% 
  ggplot(aes(x = salinity, y = size, colour = season, group = season)) + 
  facet_wrap(region~.) + 
  geom_point(size = 2, 
             position = position_dodge(width = 0.2)) + 
  #geom_line(size = 1.5) + 
  scale_colour_manual(values = season_cols) + 
  labs(y = "Prosome Length (mm)",
       x = "") + 
  theme_matt_facets(base_size = 14)

ggarrange(sal_comp_ctmax_plot, sal_comp_size_plot, nrow = 2, common.legend = T, legend = "right")


###
# 
# sal_comp_ctmax.model = lm(ctmax ~ collection_temp, data = sal_comps)
# # summary(ctmax_temp.model)
# # car::Anova(ctmax_temp.model)
# sal_comp_ctmax_resids = residuals(sal_comp_ctmax.model)
# 
# sal_comp_size.model = lm(size ~ collection_temp, data = sal_comps)
# # summary(size_temp.model)
# # car::Anova(size_temp.model)
# sal_comp_size_resids = residuals(sal_comp_size.model)
# 
# sal_comp_ctmax_resid_plot = sal_comps %>%
#   mutate(ctmax_resids = sal_comp_ctmax_resids,
#          size_resids = sal_comp_size_resids) %>%
#   ggplot(aes(x = salinity, y = ctmax_resids, colour = season, group = season)) +
#   facet_wrap(region~.) +
#   geom_point(size = 2,
#              position = position_dodge(width = 0.5)) +
#   #geom_line(size = 1.5) +
#   scale_colour_manual(values = season_cols) +
#   labs(y = "CTmax \nResiduals",
#        x = "") +
#   theme_matt_facets(base_size = 14)
# 
# sal_comp_size_resid_plot = sal_comps %>%
#   mutate(ctmax_resids = sal_comp_ctmax_resids,
#          size_resids = sal_comp_size_resids) %>%
#   ggplot(aes(x = salinity, y = size_resids, colour = season, group = season)) +
#   facet_wrap(region~.) +
#   geom_point(size = 2,
#              position = position_dodge(width = 0.5)) +
#   #geom_line(size = 1.5) +
#   scale_colour_manual(values = season_cols) +
#   labs(y = "Prosome Length \nResiduals",
#        x = "") +
#   theme_matt_facets(base_size = 14)
# 
# ggarrange(sal_comp_ctmax_resid_plot, sal_comp_size_resid_plot, nrow = 2, common.legend = T, legend = "right")

Trait Correlations

Regardless of the underlying mechanism (genetic differentiation or phenotypic plasticity), we expect that collections from warmer waters should yield copepods with higher thermal limits and smaller body sizes. Our observations largely fit this expectation, with strong increases in CTmax at higher temperatures, and a general decrease in prosome lengths as temperature increased. There was a larger correlation between CTmax and temperature than size and temperature. There are myriad reasons this might be observed, but one potential is the potential for acclimation of thermal limits. Body size is fixed in the adult stage, while CTmax can continue to vary as water temperature changes. This is indirect evidence for the importance of rapid acclimation in the observed patterns.

ctmax_temp_plot = ggplot(full_data, aes(x = collection_temp, y = ctmax)) + 
  geom_smooth(method = "lm", se = T,
              linewidth = 2, 
              colour = "grey") + 
  geom_point(aes(colour = site), 
             size = 2, alpha = 0.7) + 
  scale_colour_manual(values = site_cols) + 
  labs(y = "CTmax (°C)",
       x = "Collection Temp. (°C)") +
  theme_matt() + 
  theme(legend.position = "none")

size_temp_plot = ggplot(full_data, aes(x = collection_temp, y = size)) + 
  geom_smooth(method = "lm", se = T,
              linewidth = 2, 
              colour = "grey") + 
  geom_point(aes(colour = site), 
             size = 2, alpha = 0.7) + 
  scale_colour_manual(values = site_cols) + 
  labs(y = "Prosome Length (mm)",
       x = "Collection Temp. (°C)") +
  theme_matt() + 
  theme(legend.position = "right")

wt_temp_plot = ggplot(full_data, aes(x = collection_temp, y = warming_tol)) + 
  geom_smooth(method = "lm", se = T,
              linewidth = 2, 
              colour = "grey") + 
  geom_point(aes(colour = site), 
             size = 2, alpha = 0.7) + 
  scale_colour_manual(values = site_cols) + 
  labs(y = "Warming Tolerance (°C)",
       x = "Collection Temp. (°C)") +
  theme_matt() + 
  theme(legend.position = "right")

ggarrange(ctmax_temp_plot, wt_temp_plot, size_temp_plot, common.legend = T, legend = "bottom", nrow = 1)

One additional correlation of interest is the relationship between prosome length and CTmax. In many cases, larger body sizes are associated with cold adaptation/acclimation, and there is a general trend of decreasing thermal limits with increasing size. Shown below is the relationship between prosome length and CTmax in our data set. Individual regression lines for each site are also included - the dark grey lines in the background represent the ‘universal’ regression for that site, with individual colored regression lines for each collection. Across our collections, we see evidence for this relationship, with larger individuals having lower thermal limits.

universal_size = full_data %>% 
  ggplot(aes(x = size, y = ctmax)) + 
  # geom_smooth(data = filter(full_data, ctmax > 31), 
  #             aes(x = size, y = ctmax),
  #             method = "lm", 
  #             colour = "grey60", 
  #             se = F,
  #             linewidth = 2) + 
  geom_smooth(method = "lm", se = T,
              linewidth = 2,
              colour = "grey70") + 
  geom_point(aes(colour = site),
             size = 2, alpha = 0.7) + 
  scale_colour_manual(values = site_cols) + 
  labs(y = "CTmax (°C)",
       x = "") +
  theme_matt(base_size = 14) + 
  theme(legend.position = "right",
        axis.title.x = element_blank())

pop_size = full_data %>% 
  ggplot(aes(x = size, y = ctmax, colour = site, group = season)) + 
  facet_wrap(site~.) + 
  # geom_smooth(data = filter(full_data, ctmax > 31), 
  #             aes(x = size, y = ctmax),
  #             method = "lm", 
  #             colour = "grey60", 
  #             se = F,
  #             linewidth = 2) + 
  geom_smooth(data = full_data, 
              aes(x = size, y = ctmax, group = site), 
              colour = "grey20", method = "lm", se = F) + 
  geom_point(size = 1.3, alpha = 0.3) + 
  geom_smooth(method = "lm", se = F,
              linewidth = 1) + 
  scale_colour_manual(values = site_cols) + 
  scale_x_continuous(breaks = c(0.6, 0.8, 1)) + 
  labs(y = "CTmax (°C)",
       x = "Prosome Length (mm)") +
  theme_matt(base_size = 14) + 
  theme(legend.position = "right")

ggarrange(universal_size, pop_size, common.legend = T, legend = "none", nrow = 2)

This relationship may be affected by changes in temperature at each site, however, which can affect both body size and thermal limits. If there is a true mechanistic relationship between body size and thermal limits, we would expect to see this relationship emerge within populations, or even individual collections. Shown below is the relationship between CTmax and size residuals, acquired from regressions of these traits against collection temperature. This substantially reduces the strength of the apparent relationship, but there is still a slightly negative overall relationship, spanning both across-population, within-population, and even within-collection scales (see the Sawyer Park collections, for example).

filtered_data = full_data %>% 
  drop_na(size, ctmax) %>% 
  mutate(temp_cent = scale(collection_temp, scale = F),
         size_cent = scale(size, scale = F),
         sal_cent = scale(collection_salinity, scale = F),
         sal_type = if_else(collection_salinity > 20, "High", "Low"))

ctmax_temp.model = lm(ctmax ~ collection_temp + site, data = filtered_data)
ctmax_resids = residuals(ctmax_temp.model)

size_temp.model = lm(size ~ collection_temp + site, data = filtered_data)
size_resids = residuals(size_temp.model)

universal_resids = filtered_data %>% 
  mutate(ctmax_resids = ctmax_resids,
         size_resids = size_resids) 

all_resids = ggplot(universal_resids, aes(x = size_resids, y = ctmax_resids)) + 
  # geom_smooth(data = filter(full_data, ctmax > 31), 
  #             aes(x = size, y = ctmax),
  #             method = "lm", 
  #             colour = "grey60", 
  #             se = F,
  #             linewidth = 2) + 
  geom_smooth(method = "lm", se = T,
              linewidth = 2,
              colour = "grey70") + 
  geom_point(aes(colour = site),
             size = 2, alpha = 0.7) + 
  scale_colour_manual(values = site_cols) + 
  labs(y = "CTmax Residuals",
       x = "") +
  theme_matt(base_size = 14) + 
  theme(legend.position = "right",
        axis.title.x = element_blank())

pop_resids = ggplot(universal_resids, aes(x = size_resids, y = ctmax_resids, colour = site, group = season)) + 
  facet_wrap(site~.) + 
  # geom_smooth(data = filter(full_data, ctmax > 31), 
  #             aes(x = size, y = ctmax),
  #             method = "lm", 
  #             colour = "grey60", 
  #             se = F,
  #             linewidth = 2) + 
  geom_smooth(aes(x = size_resids, y = ctmax_resids, group = site), 
              colour = "grey20", method = "lm", se = F) + 
  geom_point(size = 1.3, alpha = 0.3) + 
  geom_smooth(method = "lm", se = F,
              linewidth = 1) + 
  scale_colour_manual(values = site_cols) + 
  labs(y = "CTmax Residuals",
       x = "Prosome Length Residuals") +
  theme_matt(base_size = 14) + 
  theme(legend.position = "right")

ggarrange(all_resids, pop_resids, common.legend = T, legend = "none", nrow = 2)

To more formally test the relationships between CTmax, collection temperature, and size, we used a linear mixed effects model, structured as ctmax ~ collection temp. + size + salinity + (1 + collection temp.|site). This examines the effects of temperature and size on CTmax, along with differences between the salinity groupings. Collection temperature and size were both centered and salinity transformed into a categorical variable (“low” salinity as anything below 20 psu, “high” salinity as anything above 20 psu) before model fitting. The model also includes random intercepts for each site and random slopes for collection temperature (i.e. - variation in the acclimation capacity of CTmax). A random intercept for season is also included.

Collection temperature and body size both had a significant effect on CTmax, but salinity type did not. The overall effect of temperature suggests an increase in CTmax of 0.17°C per °C increase in collection temperature (i.e. - an ARR value of 0.17), while increasing body sizes decrease CTmax by -3.17°C per mm (or a decrease of ~-0.317°C per tenth of a mm, which is more biologically realistic for A. tonsa). While not significant, the model suggests low salinity sites had lower thermal limits by ~0.7°C.


effects_summary = data.frame(
  "Temperature" = unname(fixef(ctmax.model)["temp_cent"]),
  "Size" = unname(fixef(ctmax.model)["size"]),
  "Salinity" = unname(fixef(ctmax.model)["sal_typeLow"])) %>%  
  select("Temperature (per degree)" = Temperature, 
         "Size (per mm)" = Size, 
         "Salinity (Low vs. High)" = Salinity)

knitr::kable(effects_summary)
Temperature (per degree) Size (per mm) Salinity (Low vs. High)
0.1664574 -3.165841 -0.6942512

By extracting the conditional mode for the random effects, we can also examine how thermal limits vary across sites beyond the influence of collection temperatures and body sizes. Shown below are these “population” values (essentially, all else being equal, how would thermal limit vary across populations). We can see that, similar to what’s been observed in common garden experiments with A. tonsa previously, significant divergences are present at only a few sites near the latitudinal extremes, with Fort Hamer and Ritchie Wharf having increased and decreased thermal limits respectively. Interestingly, both of these sites were low salinity sites, also in line with previous results suggesting gene flow between high salinity sites may constrain differentiation.

pop_effs = REsim(ctmax.model) %>% 
  dplyr::select("site" = groupID, term, mean, sd) %>% 
  filter(term == "(Intercept)") %>% 
  inner_join(site_data, by = c("site")) %>% 
  mutate(site = fct_reorder(site, lat))

season_effs = REsim(ctmax.model) %>% 
  dplyr::select("site" = groupID, term, mean, sd) %>% 
  filter(site %in% c("early", "peak", "late")) %>% 
  select("season" = site, mean, sd)

#plotREsim(REsim(ctmax.model))  # plot the interval estimates

pop_effs_plot = ggplot(pop_effs, aes(x = lat, y = mean, colour = site)) + 
  geom_hline(yintercept = 0, colour = "grey") +
  geom_errorbar(aes(ymin = mean - 1.96 * sd, ymax = mean + 1.96 * sd),
                width = 0.5, linewidth = 1) + 
  geom_point(size = 3) + 
  scale_colour_manual(values = site_cols) + 
  labs(x = "Latitude", 
       y = "Population Effect") + 
  theme_matt() + 
  theme(legend.position = "right")

pop_effs_plot

Finally, shown below are the estimated random slopes for each site. These represent the effects of collection temperature on CTmax for each site. Interestingly, these estimates diverge from the results of previous common garden experiments, which showed the strongest plasticity in high latitude sites. Here, acclimation appears to peak in mid-latitudes, and decrease at both high and low latitude sites. This suggests factors may constrain acclimation capacity in natural populations (e.g. food availability, environmental variation, pathogens, etc.).

coefficients(ctmax.model)$site %>%
  janitor::clean_names() %>%
  rownames_to_column(var = "site") %>%
  inner_join(site_data) %>% 
  mutate(site = fct_reorder(site, lat)) %>% 
  ggplot(aes(x = temp_cent, y = site)) +
  geom_point(aes(colour = site),
             size = 5) +
  scale_colour_manual(values = site_cols) +
  labs(x = "ARR") + 
  theme_matt() +
  theme(legend.position = "none",
        axis.title.y = element_blank())

Trait Variability

Shown below is the trait variation (ranges) for each site. Ranges are calculated for each collection separately.

trait_ranges = full_data %>% 
  group_by(site, season, collection_temp, collection_salinity, doy, lat) %>% 
  summarise(mean_ctmax = mean(ctmax),
            ctmax_range = max(ctmax) - min(ctmax),
            ctmax_var = var(ctmax),
            mean_size = mean(size),
            size_range = max(size) - min(size),
            size_var = var(size)) %>% 
  mutate(prop_ctmax_range = ctmax_range / mean_ctmax,
         prop_size_range = size_range / mean_size)

ctmax_range_temp = ggplot(trait_ranges, aes(x = collection_temp, y = ctmax_range)) + 
  geom_smooth(method = "lm", colour = "black") + 
  geom_point(aes(colour = site), 
             size = 3) + 
  scale_colour_manual(values = site_cols) + 
  labs(y = "CTmax Range (°C)",
       x = "Collection Temp. (°C)") +
  theme_matt() + 
  theme(legend.position = "right")

ctmax_var_temp = ggplot(trait_ranges, aes(x = collection_temp, y = ctmax_var, colour = site)) + 
  geom_point(size = 3) + 
  scale_colour_manual(values = site_cols) + 
  labs(y = "CTmax Range (°C)",
       x = "Collection Temp. (°C)") +
  theme_matt() + 
  theme(legend.position = "right")

size_range_temp = ggplot(trait_ranges, aes(x = collection_temp, y = size_range, colour = site)) + 
  geom_point(size = 3) + 
  scale_colour_manual(values = site_cols) + 
  labs(y = "Size Range (mm)",
       x = "Collection Temp. (°C)") +
  theme_matt() + 
  theme(legend.position = "right")

size_var_temp = ggplot(trait_ranges, aes(x = collection_temp, y = size_var, colour = site)) + 
  geom_point(size = 3) + 
  scale_colour_manual(values = site_cols) + 
  labs(y = "Size Range (mm)",
       x = "Collection Temp. (°C)") +
  theme_matt() + 
  theme(legend.position = "right")

ggarrange(ctmax_range_temp, size_range_temp, common.legend = T, legend = "right")

Changes in trait variance may be indicative of phenotypic selection. If selection (as opposed to acclimation) are driving seasonal changes, we may expect to see a reduction in variance in the peak samples relative to the early season samples. Note that early season collection temperatures this year were higher than expected, driven by fairly strong heatwaves across the North Atlantic. As shown in the temperature profiles for each site, the ‘early’ samples were collected just after high temperatures were reached, while ‘peak’ samples were collected after sites had experienced high temperatures for several weeks (generations). As warming tolerances were fairly high throughout this period, we will assume that selection was weak before the early samples. If the early onset of high temperatures filtered out vulnerable genotypes prior to our sampling, the results will be a conservative estimate of the effects of selection on trait variance.

Shown below is the seasonal progression of variance in CTmax for each site. For many sites, variance decreased between the early and peak samples, and then increased again in the late sample. For some sites (e.g. Esker Point), this increase in the late sample was substantial.

ggplot(trait_ranges, aes(x = season, y = ctmax_var, colour = site)) + 
  geom_line(aes(group = site), 
            linewidth = 1.5) + 
  geom_point(size = 3) + 
  scale_colour_manual(values = site_cols) + 
  labs(y = "CTmax Variance",
       x = "Season") +
  theme_matt() + 
  theme(legend.position = "right", 
        legend.title.align = 0.125)

Shown below is the seasonal progression of variance in body size. A similar pattern of decreasing variance in peak samples relative to early and late samples is again seen for many sites. The obvious exception is the Esker Point sample, which saw the opposite trend.

ggplot(trait_ranges, aes(x = season, y = size_var, colour = site)) + 
  geom_line(aes(group = site), 
            linewidth = 1.5) + 
  geom_point(size = 3) + 
  scale_colour_manual(values = site_cols) + 
  labs(y = "CTmax Variance",
       x = "Season") +
  theme_matt() + 
  theme(legend.position = "right", 
        legend.title.align = 0.125)

Shown below are the seasonal changes in trait variance for each site individually.

ggplot(trait_ranges, aes(x = season, y = ctmax_var, colour = site)) + 
  facet_wrap(site~.) + 
  geom_line(aes(group = site), 
            linewidth = 1.5) + 
  geom_point(size = 3) + 
  scale_colour_manual(values = site_cols) + 
  labs(y = "CTmax Variance",
       x = "Season") +
  theme_matt() + 
  theme(legend.position = "none", 
        legend.title.align = 0.125)


ggplot(trait_ranges, aes(x = season, y = size_var, colour = site)) + 
  facet_wrap(site~.) + 
  geom_line(aes(group = site), 
            linewidth = 1.5) + 
  geom_point(size = 3) + 
  scale_colour_manual(values = site_cols) + 
  labs(y = "Size Variance",
       x = "Season") +
  theme_matt() + 
  theme(legend.position = "none", 
        legend.title.align = 0.125)


knitr::knit_exit()
LS0tCnRpdGxlOiAiQ29tcGFyaW5nIHNlYXNvbmFsIGFuZCBsYXRpdHVkaW5hbCBwYXR0ZXJucyBpbiB0aGVybWFsIGFkYXB0YXRpb24iCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OiAKICBodG1sX2RvY3VtZW50OgogICAgICAgICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICAgICAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICAgICAgICB0b2M6IHRydWUKICAgICAgICAgIHRvY19mbG9hdDogdHJ1ZQogIGdpdGh1Yl9kb2N1bWVudDoKICAgICAgICAgIGh0bWxfcHJldmlldzogZmFsc2UKICAgICAgICAgIHRvYzogdHJ1ZQogICAgICAgICAgdG9jX2RlcHRoOiAzCi0tLQoKYGBge3J9CiMgVE8gRE8gCiMgLSBGcmFtZXdvcmsgZm9yIHF1YW50aWZ5aW5nIHRoZSBlZmZlY3RzIG9mIHdpdGhpbi0gYW5kIGFjcm9zcy1wb3B1bGF0aW9uIHZhcmlhdGlvbiBpbiB0aGVybWFsIGxpbWl0cyB0byBzcGF0aWFsIHBhdHRlcm5zIGluIHZ1bG5lcmFiaWxpdHkgdG8gd2FybWluZy4gQ29tcGFyaW5nIHByZWRpY3Rpb25zIGJhc2VkIG9uIDEpIG1lZGlhbiwgMikgb3ZlcmFsbCBDVG1heCB2cy4gdGVtcCByZWdyZXNzaW9uLCAzKSBwb3B1bGF0aW9uIHZhcmlhdGlvbiBpbiBpbnRlcmNlcHRzLCA0KSBwb3B1bGF0aW9uIHZhcmlhdGlvbiBpbiBib3RoIHNsb3BlIGFuZCBpbnRlcmNlcHQuIFRoZSBlbmQgbWV0cmljIEkgY291bGQgdXNlIHRvIGNvbXBhcmUgYWNyb3NzIHNjZW5hcmlvcyBpcyBpKSB0aGUgY3VtdWxhdGl2ZSBhbW91bnQgb2YgdW5kZXJlc3RpbWF0aW9uIChzdW1tZWQgYWNyb3NzIHBvcHVsYXRpb25zKSBvciBpaSkgdGhlIG51bWJlciBvZiBzaXRlcyB0aGF0IGhhdmUgb3ZlcmVzdGltYXRlZCBXVCwgb3IgaWlpKSB0aGUgc2xvcGUgb2YgV1QgKGxvY2FsIGFkYXB0YXRpb24gYW5kIHNlYXNvbmFsIGFjY2xpbWF0aW9uIHNob3VsZCByZXN1bHQgaW4gbW9yZSBzaGFsbG93IHNsb3BlcykuIApgYGAKCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1ULCBtZXNzYWdlID0gRiwgd2FybmluZyA9IEYsIGVjaG8gPSBGfQoKa25pdHI6Om9wdHNfY2h1bmskc2V0KAogIGVjaG8gPSBrbml0cjo6aXNfaHRtbF9vdXRwdXQoKSwKICBmaWcuYWxpZ24gPSAiY2VudGVyIiwKICBmaWcucGF0aCA9ICIuLi9GaWd1cmVzL21hcmtkb3duLyIsCiAgZGV2ID0gYygicG5nIiwgInBkZiIpLAogIG1lc3NhZ2UgPSBGQUxTRSwKICB3YXJuaW5nID0gRkFMU0UsCiAgY29sbGFwc2UgPSBUCikKCnRoZW1lX21hdHQgPSBmdW5jdGlvbihiYXNlX3NpemUgPSAxOCwKICAgICAgICAgICAgICAgICAgICAgIGRhcmtfdGV4dCA9ICJncmV5MjAiKXsKICBtaWRfdGV4dCA8LSAgbW9ub2Nocm9tZVI6OmdlbmVyYXRlX3BhbGV0dGUoZGFya190ZXh0LCAiZ29fbGlnaHRlciIsIG5fY29sb3VycyA9IDUpWzJdCiAgbGlnaHRfdGV4dCA8LSAgbW9ub2Nocm9tZVI6OmdlbmVyYXRlX3BhbGV0dGUoZGFya190ZXh0LCAiZ29fbGlnaHRlciIsIG5fY29sb3VycyA9IDUpWzNdCiAgCiAgdGhlbWVfcHVicihiYXNlX2ZhbWlseT0ic2FucyIpICUrcmVwbGFjZSUgCiAgICB0aGVtZSgKICAgICAgcGFuZWwuYmFja2dyb3VuZCAgPSBlbGVtZW50X3JlY3QoZmlsbD0idHJhbnNwYXJlbnQiLCBjb2xvdXI9TkEpLCAKICAgICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9InRyYW5zcGFyZW50IiwgY29sb3VyPU5BKSwgCiAgICAgIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9InRyYW5zcGFyZW50IiwgY29sb3VyPU5BKSwKICAgICAgbGVnZW5kLmtleSA9IGVsZW1lbnRfcmVjdChmaWxsPSJ0cmFuc3BhcmVudCIsIGNvbG91cj1OQSksCiAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoY29sb3VyID0gbWlkX3RleHQsIGxpbmVoZWlnaHQgPSAxLjEpLAogICAgICB0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplICogMS41LAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSBkYXJrX3RleHQpLAogICAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG91ciA9IG1pZF90ZXh0KSwKICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSBiYXNlX3NpemUgKiAxLjIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW4gPSB1bml0KGMoMywgMCwgMCwgMCksICJtbSIpKSwKICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSBiYXNlX3NpemUgKiAxLjIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW4gPSB1bml0KGMoMCwgNSwgMCwgMCksICJtbSIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuZ2xlID0gOTApLAogICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPWJhc2Vfc2l6ZSAqIDAuOSksCiAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplICogMC45LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhY2UgPSAiYm9sZCIpLAogICAgICBwbG90Lm1hcmdpbiA9IG1hcmdpbigwLjI1LCAwLjI1LCAwLjI1LCAwLjI1LCJjbSIpCiAgICApCn0KCnRoZW1lX21hdHRfZmFjZXRzID0gZnVuY3Rpb24oYmFzZV9zaXplID0gMTgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGFya190ZXh0ID0gImdyZXkyMCIpewogIG1pZF90ZXh0IDwtICBtb25vY2hyb21lUjo6Z2VuZXJhdGVfcGFsZXR0ZShkYXJrX3RleHQsICJnb19saWdodGVyIiwgbl9jb2xvdXJzID0gNSlbMl0KICBsaWdodF90ZXh0IDwtICBtb25vY2hyb21lUjo6Z2VuZXJhdGVfcGFsZXR0ZShkYXJrX3RleHQsICJnb19saWdodGVyIiwgbl9jb2xvdXJzID0gNSlbM10KICAKICB0aGVtZV9idyhiYXNlX2ZhbWlseT0ic2FucyIpICUrcmVwbGFjZSUgCiAgICB0aGVtZSgKICAgICAgcGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgcGFuZWwuYmFja2dyb3VuZCAgPSBlbGVtZW50X3JlY3QoZmlsbD0idHJhbnNwYXJlbnQiLCBjb2xvdXI9TkEpLCAKICAgICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9InRyYW5zcGFyZW50IiwgY29sb3VyPU5BKSwgCiAgICAgIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9InRyYW5zcGFyZW50IiwgY29sb3VyPU5BKSwKICAgICAgbGVnZW5kLmtleSA9IGVsZW1lbnRfcmVjdChmaWxsPSJ0cmFuc3BhcmVudCIsIGNvbG91cj1OQSksCiAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoY29sb3VyID0gbWlkX3RleHQsIGxpbmVoZWlnaHQgPSAxLjEpLAogICAgICBzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSksCiAgICAgIHRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSBiYXNlX3NpemUgKiAxLjUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG91ciA9IGRhcmtfdGV4dCksCiAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3VyID0gbWlkX3RleHQpLAogICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSAqIDEuMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcmdpbiA9IHVuaXQoYygzLCAwLCAwLCAwKSwgIm1tIikpLAogICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSAqIDEuMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcmdpbiA9IHVuaXQoYygwLCA1LCAwLCAwKSwgIm1tIiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5nbGUgPSA5MCksCiAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9YmFzZV9zaXplICogMC45KSwKICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSBiYXNlX3NpemUgKiAwLjksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFjZSA9ICJib2xkIiksCiAgICAgIHBsb3QubWFyZ2luID0gbWFyZ2luKDAuMjUsIDAuMjUsIDAuMjUsIDAuMjUsImNtIikKICAgICkKfQoKc2l0ZV9jb2xzID0gYygiS2V5IExhcmdvIiA9ICJpbmRpYW5yZWQ0IiwgCiAgICAgICAgICAgICAgIk1hbmF0ZWUgUml2ZXIiID0gImNvcmFsIiwgCiAgICAgICAgICAgICAgIkZ0LiBIYW1lciIgPSAiY29yYWwzIiwKICAgICAgICAgICAgICAiVHlsZXIgQ292ZSIgPSAiZ29sZGVucm9kMSIsCiAgICAgICAgICAgICAgIkdhbmV5J3MgV2hhcmYiID0gImRhcmtnb2xkZW5yb2QzIiwgCiAgICAgICAgICAgICAgIkVza2VyIFBvaW50IiA9ICJkYXJrc2VhZ3JlZW4zIiwKICAgICAgICAgICAgICAiU2F3eWVyIFBhcmsiID0gInBhbGVncmVlbjQiLCAKICAgICAgICAgICAgICAiU3QuIFRob21hcyBkZSBLZW50IFdoYXJmIiA9ICJzdGVlbGJsdWUyIiwKICAgICAgICAgICAgICAiUml0Y2hpZSBXaGFyZiIgPSAic3RlZWxibHVlNCIpCmBgYAoKIyMgU2l0ZSBDaGFyYWN0ZXJpc3RpY3MKCmBgYHtyfQpzaXRlX3RlbXBzID0gZnVsbF9kYXRhICU+JSAKICBkcGx5cjo6c2VsZWN0KHNpdGUsIGxhdCwgc2Vhc29uLCBkb3ksIGNvbGxlY3Rpb25fdGVtcCwgY29sbGVjdGlvbl9zYWxpbml0eSkgJT4lICAKICBkaXN0aW5jdCgpICU+JSAKICBmaWx0ZXIoZG95ID4gMTAwKSAKYGBgCgpDb3BlcG9kcyB3ZXJlIGNvbGxlY3RlZCBieSBzdXJmYWNlIHRvdyBmcm9tIHNpdGVzIGFjcm9zcyB0aGUgV2VzdGVybiBBdGxhbnRpYyBhdCBzZXZlcmFsIHRpbWVzIHRocm91Z2hvdXQgdGhlIHllYXIuIFRoZSBzaXRlcyBhcmUgc2hvd24gYmVsb3cuIFRlbXBlcmF0dXJlcyBhdCB0aGUgdGltZSBvZiBjb2xsZWN0aW9uIHdlcmUgbWVhc3VyZWQgdXNpbmcgYSBtYW51YWwgdGhlcm1vbWV0ZXIuIEFjcm9zcyB0aGUgZW50aXJlIHNldCBvZiBjb2xsZWN0aW9ucywgdGVtcGVyYXR1cmUgcmFuZ2VkIGZyb20gYHIgbWluKHNpdGVfdGVtcHMkY29sbGVjdGlvbl90ZW1wKWDCsEMgdG8gYHIgbWF4KHNpdGVfdGVtcHMkY29sbGVjdGlvbl90ZW1wKWDCsEMuCgpgYGB7ciBzaXRlLWNoYXJzLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9Nn0KY29vcmRzID0gc2l0ZV9kYXRhICU+JQogIGRwbHlyOjpzZWxlY3Qoc2l0ZSwgbG9uZywgbGF0KSAlPiUKICBkaXN0aW5jdCgpCgpzaXRlX21hcCA9IG1hcF9kYXRhKCJ3b3JsZCIpICU+JSAKICBmaWx0ZXIocmVnaW9uICVpbiUgYygiVVNBIiwgIkNhbmFkYSIpKSAlPiUgCiAgZ2dwbG90KCkgKyAKICBnZW9tX3BvbHlnb24oYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwKICAgICAgICAgICAgICAgZmlsbCA9ICJsaWdodGdyZXkiKSArIAogIGNvb3JkX21hcCh4bGltID0gYygtODUsLTYwKSwKICAgICAgICAgICAgeWxpbSA9IGMoMjUsIDQ4KSkgKyAKICBnZW9tX3BvaW50KGRhdGEgPSBjb29yZHMsCiAgICAgICAgICAgICBtYXBwaW5nID0gYWVzKHggPSBsb25nLCB5ID0gbGF0LCBjb2xvdXIgPSBzaXRlKSwKICAgICAgICAgICAgIHNpemUgPSAzKSArCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh4ID0gIkxvbmdpdHVkZSIsIAogICAgICAgeSA9ICJMYXRpdHVkZSIpICsgCiAgdGhlbWVfbWF0dChiYXNlX3NpemUgPSAxNikKCnNpdGVfdGVtcF9wbG90ID0gZ2dwbG90KHNpdGVfdGVtcHMsIGFlcyh4ID0gZG95LCB5ID0gY29sbGVjdGlvbl90ZW1wLCBjb2xvdXIgPSBzaXRlKSkgKyAKICBnZW9tX2xpbmUobGluZXdpZHRoID0gMikgKyAKICBnZW9tX3BvaW50KHNpemUgPSA1KSArCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh5ID0gIlRlbXBlcmF0dXJlICjCsEMpIiwKICAgICAgIHggPSAiRGF5IG9mIHRoZSBZZWFyIikgKwogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgpnZ2FycmFuZ2Uoc2l0ZV9tYXAsIHNpdGVfdGVtcF9wbG90LCBjb21tb24ubGVnZW5kID0gVCwgbGVnZW5kID0gImJvdHRvbSIpCmBgYAoKQ29sbGVjdGlvbnMgYWltZWQgdG8gb2J0YWluIGNvcGVwb2RzIG5lYXIgdGhlIG9uc2V0IG9mIHBlYWsgdGVtcGVyYXR1cmVzLCBhZnRlciBwZWFrIHRlbXBlcmF0dXJlcywgYW5kIHRoZW4gYXQgbG93IHRlbXBlcmF0dXJlcy4gUmVnaW9uYWwgZGF0YSBpcyBub3QgYXZhaWxhYmxlIGZvciBhbGwgc2l0ZXMsIHNvIGhlcmUgd2UndmUgcGllY2VkIHRvZ2V0aGVyIGRhaWx5IHRlbXBlcmF0dXJlIHZhbHVlcyBmcm9tIGVpdGhlciBsb2NhbCB0ZW1wZXJhdHVyZSBzZW5zb3JzIChzaXRlcyBpbiBGbG9yaWRhIGFuZCB0aGUgQ2hlc2FwZWFrZSkgYW5kIGhpZ2ggcmVzb2x1dGlvbiBzYXRlbGxpdGUgdGVtcGVyYXR1cmUgZGF0YSAoQ29ubmVjdGljdXQsIE1haW5lLCBhbmQgdGhlIENhbmFkaWFuIHNpdGVzKS4gVGhpcyBzYXRlbGxpdGUgZGF0YSBjb21lcyBmcm9tIHRoZSBOT0FBIDEvNMKwIERhaWx5IE9wdGltdW0gSW50ZXJwb2xhdGlvbiBTZWEgU3VyZmFjZSBUZW1wZXJhdHVyZSAoT0lTU1QpLiAKClRoZXNlIHRlbXBlcmF0dXJlIHByb2ZpbGVzIGFyZSBzaG93biBiZWxvdywgd2l0aCB0aGUgdGVtcGVyYXR1cmVzIG1lYXN1cmVkIGR1cmluZyB0aGUgdGltZSBvZiBjb2xsZWN0aW9uIGluY2x1ZGVkIGZvciBjb21wYXJpc29uIEluIHNldmVyYWwgY2FzZXMgY29sbGVjdGlvbiB0ZW1wZXJhdHVyZSBkb2VzIG5vdCBtYXRjaCB0aGUgcmVjb3JkZWQgZGFpbHkgYXZlcmFnZXMsIGJ1dCB0aGUgdGVtcGVyYXR1cmUgcmVjb3JkcyBkbyBnaXZlIGEgZ2VuZXJhbCBzZW5zZSBvZiB0aGUgdGltaW5nIG9mIHNlYXNvbmFsIG1heGltYS4gSW4gZ2VuZXJhbCwgdGhlIGZpcnN0IHNhbXBsZSBmcm9tIGVhY2ggc2l0ZSBmZWxsIGp1c3QgYWZ0ZXIgdGhlIHNpdGUgcmVhY2hlZCB0aGUgd2FybWVzdCBwZXJpb2QuIFRoZSBleGNlcHRpb24gdG8gdGhhdCBwYXR0ZXJuIGlzIGluIEZsb3JpZGEsIHdoZXJlIGNvbGxlY3Rpb25zIG9jY3VycmVkIGFmdGVyIGFuIGV4dGVuZGVkIHBlcmlvZCBvZiBoaWdoIHRlbXBlcmF0dXJlcy4gCgpgYGB7ciBjb250aW51b3VzLXRlbXBzLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD02fQp0ZW1wX3Byb2ZpbGVzID0gdGVtcF9wcm9maWxlcyAlPiUgCiAgZmlsdGVyKGRveSA+IDEwMCkgJT4lIAogIG11dGF0ZShyZWdpb24gPSBmY3RfcmVsZXZlbChyZWdpb24sICJGbG9yaWRhIiwgIkNoZXNhcGVha2UiLCAiQ29ubmVjdGljdXQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWFpbmUiLCAiU2hlZGlhYyIsICJNaXJhbWljaGkiKSkKCnNpdGVfdGVtcHMyID0gc2l0ZV90ZW1wcyAlPiUgCiAgbXV0YXRlKHJlZ2lvbiA9IGNhc2Vfd2hlbigKICAgIHNpdGUgPT0gIk1hbmF0ZWUgUml2ZXIiIH4gIkZsb3JpZGEiLAogICAgc2l0ZSA9PSAiRnQuIEhhbWVyIiB+ICJGbG9yaWRhIiwKICAgIHNpdGUgPT0gIlR5bGVyIENvdmUiIH4gIkNoZXNhcGVha2UiLAogICAgc2l0ZSA9PSAiR2FuZXkncyBXaGFyZiIgfiAiQ2hlc2FwZWFrZSIsCiAgICBzaXRlID09ICJFc2tlciBQb2ludCIgfiAiQ29ubmVjdGljdXQiLAogICAgc2l0ZSA9PSAiU2F3eWVyIFBhcmsiIH4gIk1haW5lIiwKICAgIHNpdGUgPT0gIlN0LiBUaG9tYXMgZGUgS2VudCBXaGFyZiIgfiAiU2hlZGlhYyIsCiAgICBzaXRlID09ICJSaXRjaGllIFdoYXJmIiB+ICJNaXJhbWljaGkiKSwKICAgIHJlZ2lvbiA9IGZjdF9yZWxldmVsKHJlZ2lvbiwgIkZsb3JpZGEiLCAiQ2hlc2FwZWFrZSIsICJDb25uZWN0aWN1dCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAiTWFpbmUiLCAiU2hlZGlhYyIsICJNaXJhbWljaGkiKSkKCmdncGxvdCh0ZW1wX3Byb2ZpbGVzLCBhZXMoeCA9IGRveSwgeSA9IHRlbXBfYykpICsgCiAgZmFjZXRfd3JhcChyZWdpb25+LikgKyAKICBnZW9tX3BvaW50KGRhdGEgPSBzaXRlX3RlbXBzMiwKICAgICAgICAgICAgIGFlcyh4ID0gZG95LCB5ID0gY29sbGVjdGlvbl90ZW1wLCBjb2xvdXIgPSBzaXRlKSwKICAgICAgICAgICAgIHNpemUgPSAzKSArCiAgZ2VvbV9saW5lKCkgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgKyAKICBsYWJzKHggPSAiRGF5IG9mIHRoZSBZZWFyIiwgCiAgICAgICB5ID0gIk1lYW4gRGFpbHkgVGVtcC4gKMKwQykiKSArIAogIHRoZW1lX21hdHRfZmFjZXRzKCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsIAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzIwLCBoanVzdCA9IDAsIHZqdXN0ID0gMC41KSkKYGBgCgoKRXhhY3QgbG9jYXRpb25zIGZvciB0aGUgc2l0ZXMgYXJlIHByb3ZpZGVkIGhlcmUuIAoKYGBge3Igc2l0ZS10YWJsZX0Kc2l0ZV9kYXRhICU+JSAgCiAgYXJyYW5nZShsYXQpICU+JSAgCiAgc2VsZWN0KCJTaXRlIiA9IHNpdGUsICJSZWdpb24iID0gcmVnaW9uLCAiTGF0IiA9IGxhdCwgIkxvbmciID0gbG9uZykgJT4lIAogIGtuaXRyOjprYWJsZShhbGlnbiA9ICJjIikKYGBgCgpOZXN0ZWQgd2l0aGluIGVhY2ggb2YgdGhlIHRocmVlIHJlZ2lvbnMgKFNvdXRoLCBDZW50cmFsLCBhbmQgTm9ydGhlcm4gcmVnaW9ucykgYXJlIHBhaXJzIG9mIGxvdyBhbmQgaGlnaCBzYWxpbml0eSBzaXRlczogICAgCgpgYGB7ciBzYWwtdGFibGV9CmRhdGEuZnJhbWUoIlJlZ2lvbiIgPSBjKCJTb3V0aCIsICJDZW50cmFsIiwgIk5vcnRoIiksCiAgICAgICAgICAgIkxvdyBTYWxpbml0eSIgPSBjKCJGdC4gSGFtZXIiLCAiR2FuZXkncyBXaGFyZiIsICJSaXRjaGllIFdoYXJmIiksCiAgICAgICAgICAgIkhpZ2ggU2FsaW5pdHkiID0gYygiTWFuYXRlZSBSaXZlciIsICJUeWxlciBDb3ZlIiwgIlN0LiBUaG9tYXMgZGUgS2VudCBXaGFyZiIpKSAlPiUgCiAga25pdHI6OmthYmxlKGFsaWduID0gImMiKQpgYGAKClwgCgpUaGVyZSBhcmUgZmFpcmx5IHdlbGwtZXN0YWJsaXNoZWQgZGl2ZXJnZW5jZXMgYmV0d2VlbiBoaWdoIHNhbGluaXR5IGFuZCBsb3cgc2FsaW5pdHkgcG9wdWxhdGlvbnMgb2YgKkFjYXJ0aWEgdG9uc2EqLiBUaGVzZSBzZXRzIG9mIGdlb2dyYXBoaWNhbGx5IHByb3hpbWF0ZSBidXQgaXNvbGF0ZWQgcG9wdWxhdGlvbnMgcHJvdmlkZSBpbmRlcGVuZGVudCBjb21wYXJpc29ucyBvZiB0aGUgZWZmZWN0cyBvZiBzZWFzb25hbGl0eS4gU2hvd24gaGVyZSBhcmUgdGhlIGNvbGxlY3Rpb24gY29uZGl0aW9ucyBmb3IgdGhlc2UgcGFpcnMgb2Ygc2l0ZXMuIFRlbXBlcmF0dXJlIHdhcyB0eXBpY2FsbHkgc2ltaWxhciBhY3Jvc3MgdGhlIHBhaXJzIHdpdGhpbiBlYWNoIGNvbGxlY3Rpb24sIHdoaWxlIHNhbGluaXR5IGRpZmZlcmVuY2VzIHdlcmUgZmFpcmx5IHN0YWJsZSBhY3Jvc3MgY29sbGVjdGlvbnMuIAoKYGBge3Igc2Vhc29uLXNhbC1jb21wcywgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9OH0Kc2Vhc29uX2NvbHMgPSBjKCJlYXJseSIgPSAiZ3JleTc1IiwgCiAgICAgICAgICAgICAgICAicGVhayIgPSAiZ3JleTUwIiwgCiAgICAgICAgICAgICAgICAibGF0ZSIgPSAiZ3JleTI1IikKCnNhbF9yZWdpb25zID0gZGF0YS5mcmFtZShyZWdpb24gPSByZXAoYygiU291dGgiLCAiQ2VudHJhbCIsICJOb3J0aCIpLCBlYWNoID0gMiksIAogICAgICAgICAgICAgICAgICAgICAgICAgc2l0ZSA9IGMoIkZ0LiBIYW1lciIsICJNYW5hdGVlIFJpdmVyIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiR2FuZXkncyBXaGFyZiIsICJUeWxlciBDb3ZlIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUml0Y2hpZSBXaGFyZiIsICJTdC4gVGhvbWFzIGRlIEtlbnQgV2hhcmYiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIHNhbGluaXR5ID0gYygibG93IiwgImhpZ2giKSkKCnNhbF9jb21wcyA9IGZ1bGxfZGF0YSAlPiUgCiAgZmlsdGVyKHNpdGUgJWluJSBzYWxfcmVnaW9ucyRzaXRlKSAlPiUgCiAgaW5uZXJfam9pbihzYWxfcmVnaW9ucywgYnkgPSBjKCJzaXRlIikpICU+JSAKICBzZWxlY3QoIHJlZ2lvbiA9IHJlZ2lvbi55LCBzaXRlLCBzYWxpbml0eSwgc2Vhc29uLCBkb3ksIGNvbGxlY3Rpb25fdGVtcCwgY29sbGVjdGlvbl9zYWxpbml0eSwKICAgICAgICAgIHNpemUsIGN0bWF4LCB3YXJtaW5nX3RvbCkgJT4lIAogIG11dGF0ZShzYWxpbml0eSA9IGZjdF9yZWxldmVsKHNhbGluaXR5LCAibG93IiwgImhpZ2giKSwKICAgICAgICAgcmVnaW9uID0gZmN0X3JlbGV2ZWwocmVnaW9uLCAiU291dGgiLCAiQ2VudHJhbCIsICJOb3J0aCIpKQoKc2FsX2NvbXBfdGVtcHMgPSBzYWxfY29tcHMgJT4lICAKICBzZWxlY3Qoc2FsaW5pdHksIHNlYXNvbiwgcmVnaW9uLCBjb2xsZWN0aW9uX3RlbXAsIGNvbGxlY3Rpb25fc2FsaW5pdHkpICU+JSAKICBkaXN0aW5jdCgpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzYWxpbml0eSwgeSA9IGNvbGxlY3Rpb25fdGVtcCwgY29sb3VyID0gc2Vhc29uLCBncm91cCA9IHNlYXNvbikpICsgCiAgZmFjZXRfd3JhcChyZWdpb25+LikgKyAKICBnZW9tX2xpbmUobGluZXdpZHRoID0gMS41KSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDQpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzZWFzb25fY29scykgKyAKICBsYWJzKHkgPSAiQ29sbGVjdGlvbiBUZW1wLiAowrBDKSIsCiAgICAgICB4ID0gIiIpICsgCiAgdGhlbWVfbWF0dF9mYWNldHMoYmFzZV9zaXplID0gMTQpCgpzYWxfY29tcF9zYWwgPSBzYWxfY29tcHMgJT4lICAKICBzZWxlY3Qoc2FsaW5pdHksIHNlYXNvbiwgcmVnaW9uLCBjb2xsZWN0aW9uX3RlbXAsIGNvbGxlY3Rpb25fc2FsaW5pdHkpICU+JSAKICBkaXN0aW5jdCgpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzYWxpbml0eSwgeSA9IGNvbGxlY3Rpb25fc2FsaW5pdHksIGNvbG91ciA9IHNlYXNvbiwgZ3JvdXAgPSBzZWFzb24pKSArIAogIGZhY2V0X3dyYXAocmVnaW9ufi4pICsgCiAgZ2VvbV9saW5lKGxpbmV3aWR0aCA9IDEuNSkgKyAKICBnZW9tX3BvaW50KHNpemUgPSA0KSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2Vhc29uX2NvbHMpICsgCiAgbGFicyh5ID0gIkNvbGxlY3Rpb24gU2FsaW5pdHkgKHBzdSkiLAogICAgICAgeCA9ICJTYWxpbml0eSIpICsgCiAgdGhlbWVfbWF0dF9mYWNldHMoYmFzZV9zaXplID0gMTQpCgpnZ2FycmFuZ2Uoc2FsX2NvbXBfdGVtcHMsIHNhbF9jb21wX3NhbCwgbnJvdyA9IDIsIGNvbW1vbi5sZWdlbmQgPSBULCBsZWdlbmQgPSAicmlnaHQiKQpgYGAKClRoZSBsYXRpdHVkaW5hbCBncmFkaWVudCBjb3ZlcnMgYSB3aWRlIHJhbmdlIG9mIHNlYXNvbmFsaXR5LiBTaG93biBiZWxvdyBpcyB0aGUgdGVtcGVyYXR1cmUgcmFuZ2UuIFdoaWxlIGJhc2VkIG9uIGNvbGxlY3Rpb24gdGVtcGVyYXR1cmVzLCBhbmQgdGhlcmVmb3JlIGFuIHVuZGVyZXN0aW1hdGUgb2YgdGhlIHRvdGFsIHNlYXNvbmFsIHJhbmdlIG9mIHRlbXBlcmF0dXJlcywgdGhlc2UgcGF0dGVybnMgYXJlIHJlcHJlc2VudGF0aXZlIG9mIHRoZSBleHBlY3RlZCBsYXRpdHVkaW5hbCBncmFkaWVudCBpbiBzZWFzb25hbGl0eS4gCgpgYGB7ciBsYXQtdGVtcC1yYW5nZS1wbG90LCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD01fQpzaXRlX3RlbXBzICU+JSAKICBncm91cF9ieShzaXRlLCBsYXQpICU+JSAgCiAgc3VtbWFyaXNlKHRlbXBfcmFuZ2UgPSBtYXgoY29sbGVjdGlvbl90ZW1wKSAtIG1pbihjb2xsZWN0aW9uX3RlbXApKSAlPiUgIAogIGdncGxvdChhZXMoeCA9IGxhdCwgeSA9IHRlbXBfcmFuZ2UpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG91ciA9IHNpdGUpLAogICAgICAgICAgICAgc2l6ZSA9IDMpICsgCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgKyAKICBsYWJzKHggPSAiTGF0aXR1ZGUiLCAKICAgICAgIHkgPSAiQ29sbGVjdGlvbiBUZW1wLiBSYW5nZSAowrBDKSIpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKYGBgCgoKIyMgUGhlbm90eXBpYyBNZWFzdXJlbWVudHMgCgojIyMgQ3JpdGljYWwgVGhlcm1hbCBMaW1pdHMKCkEgdG90YWwgb2YgYHIgZGltKGFsbF9kYXRhKVsxXWAgaW5kaXZpZHVhbHMgd2VyZSBleGFtaW5lZC4gQ3JpdGljYWwgdGhlcm1hbCBsaW1pdHMgYW5kIGJvZHkgc2l6ZSBtZWFzdXJlbWVudHMgd2VyZSBtYWRlIGJlZm9yZSBpbmRpdmlkdWFscyB3ZXJlIHByZXNlcnZlZCBpbiBldGhhbm9sLiBXZSBleGNsdWRlZCBkYXRhIGZvciBgciBkaW0oZXhjbHVkZWQpWzFdYCBpbmRpdmlkdWFscywgZGV0YWlsZWQgYmVsb3cuIFRoZXNlIGluZGl2aWR1YWxzIGhhZCBlaXRoZXIgdmVyeSBsb3cgQ1RtYXggb3Igd2VyZSwgdXBvbiByZS1leGFtaW5hdGlvbiBvZiBwaG90b2dyYXBocywgaWRlbnRpZmllZCBhcyBqdXZlbmlsZXMgaW5zdGVhZCBvZiBtYXR1cmUgZmVtYWxlcy4gV2l0aCB0aGVzZSBpbmRpdmlkdWFscyBleGNsdWRlZCwgKip0aGUgZnVsbCBkYXRhIHNldCBjb250YWlucyBgciBkaW0oZnVsbF9kYXRhKVsxXWAgcGhlbm90eXBlZCBpbmRpdmlkdWFscyoqLiAgIAoKYGBge3IgZXhjbHVkZWQtaW5kc30KZXhjbHVkZWQgJT4lIAogIHNlbGVjdChyZWdpb24sIHNpdGUsIHNlYXNvbiwgY29sbGVjdGlvbl90ZW1wLCBjb2xsZWN0aW9uX3NhbGluaXR5LCByZXBsaWNhdGUsIHR1YmUsIGN0bWF4LCBzaXplKSAlPiUgCiAga25pdHI6OmthYmxlKGFsaWduID0gImMiKQpgYGAKCkNyaXRpY2FsIHRoZXJtYWwgbWF4aW1hIChDVG1heCkgd2FzIG1lYXN1cmVkIHVzaW5nIGEgY3VzdG9tIHNldHVwLiBUaGUgbWV0aG9kIHVzZXMgYSBzdGFuZGFyZCBkeW5hbWljIHJhbXBpbmcgYXNzYXkgdG8gZGV0ZXJtaW5lIHRoZSBtYXhpbXVtIHRlbXBlcmF0dXJlIGluZGl2aWR1YWxzIGNvdWxkIHN1c3RhaW4gbm9ybWFsIGZ1bmN0aW9uaW5nLiBUaGlzIGRpZmZlcnMgZnJvbSBsZXRoYWwgdGVtcGVyYXR1cmVzLCBhbmQgaW5kZWVkLCBhbGwgaW5kaXZpZHVhbHMgb2JzZXJ2ZWQgc28gZmFyIHJlY292ZXJlZCBmb2xsb3dpbmcgdGhlIGFzc2F5LgoKSW5kaXZpZHVhbHMgd2VyZSByZXN0ZWQgZm9yIG9uZSBob3VyIGFmdGVyIGNvbGxlY3Rpb24gYmVmb3JlIHRoZSBhc3NheS4gRHVyaW5nIHRoZSBhc3NheSwgY29wZXBvZHMgd2VyZSBoZWxkIGluIGFydGlmaWNpYWwgc2Vhd2F0ZXIsIGNvbXBvc2VkIG9mIGJvdHRsZWQgc3ByaW5nIHdhdGVyIGFuZCBJbnN0YW50IE9jZWFuIHNhbHQgbWl4IGFkanVzdGVkIHRvIG1hdGNoIGNvbGxlY3Rpb24gc2FsaW5pdGllcy4gRHVyaW5nIHRoZSBhc3NheSwgc2V2ZXJhbCAnY29udHJvbCcgaW5kaXZpZHVhbHMgd2VyZSBtYWludGFpbmVkIGluIHRoaXMgc29sdXRpb24gYXQgYW1iaWVudCB0ZW1wZXJhdHVyZXMgd2l0aG91dCB0aGUgdGVtcGVyYXR1cmUgcmFtcCB0byBlbnN1cmUgdGhhdCB0aGVyZSB3YXMgbm8gYmFja2dyb3VuZCBtb3J0YWxpdHkuIFdoZW4gc29ydGluZyBpbmRpdmlkdWFscyBmcm9tIHRoZSBwbGFua3RvbiB0b3cgY29udGVudHMsIHRoZXkgd2VyZSBoZWxkIGluIGEgNTA6NTAgbWl4IG9mIDYwIHVtIGZpbHRlcmVkIHdhdGVyIGZyb20gdGhlIGNvbGxlY3Rpb24gc2l0ZSBhbmQgYXJ0aWZpY2lhbCBzZWF3YXRlciBhcyBhbiBhZGRpdGlvbmFsIGFjY2xpbWF0aW9uIHN0ZXAuIAoKU2FtcGxlIHNpemVzIHZhcmllZCBzbGlnaHRseSBhY3Jvc3MgZXhwZXJpbWVudHMsIGJ1dCBtb3N0IHNpdGVzIGhhZCAyMCBpbmRpdmlkdWFscyBtZWFzdXJlZCBwZXIgc2Vhc29uLiBUaGUgbWFqb3IgZXhjZXB0aW9ucyB3ZXJlIHRoZSBlYXJseSBzYW1wbGVzIGZyb20gdGhlIEZsb3JpZGEgc2l0ZXMgYW5kIHRoZSBsYXRlIHNhbXBsZSBmcm9tIFNhd3llciBQYXJrIChNYWluZSkuIE9ubHkgdHdvIHNldHMgb2Ygc2FtcGxlcyAocGVhayBhbmQgbGF0ZSkgd2VyZSBjb2xsZWN0ZWQgZnJvbSBGb3J0IEhhbWVyIGFuZCBNYW5hdGVlIFJpdmVyLiBObyBzYW1wbGVzIHdlcmUgY29sbGVjdGVkIGZyb20gS2V5IExhcmdvIGZvciB0aGlzIHByb2plY3QsIGFzICpBY2FydGlhIHRvbnNhKiB3YXNuJ3QgcHJlc2VudCBpbiB0aGUgd2F0ZXIgZHVyaW5nIHRoZSBwZWFrIHNlYXNvbiwgbGlrZWx5IGR1ZSB0byB0aGUgcmVjZW50IGV4dHJlbWUgaGVhdCBldmVudC4gVGhlIGxhdGUgc2Vhc29uIGNvbGxlY3Rpb24gZnJvbSBTYXd5ZXIgUGFyayBvY2N1cnJlZCBhZnRlciAqQWNhcnRpYSB0b25zYSogYWJ1bmRhbmNlIGRlY3JlYXNlZC4gU2FtcGxlcyBmcm9tIHRoaXMgcGVyaW9kIHdlcmUgZG9taW5hdGVkIGJ5ICpBY2FydGlhIGh1ZHNvbmljYSogaW5zdGVhZC4gCgpgYGB7ciBzYW1wbGUtc2l6ZS1wbG90LCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9NX0KZ2dwbG90KGZ1bGxfZGF0YSwgYWVzKHggPSBzaXRlLCBmaWxsID0gc2l0ZSkpICsgCiAgZmFjZXRfd3JhcChzZWFzb25+LikgKyAKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBjKDAsMjApLAogICAgICAgICAgICAgY29sb3VyID0gImdyZXk3MCIpICsgCiAgZ2VvbV9iYXIoKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgKyAKICBjb29yZF9mbGlwKCkgKwogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwKICAgICAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QobGluZXdpZHRoID0gMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbCA9IE5BKSwKICAgICAgICBzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF9ibGFuaygpKQpgYGAKClNob3duIGJlbG93IGFyZSB0aGUgbWVhc3VyZWQgQ1RtYXggdmFsdWVzLiBOb3RlOiBDVG1heCB2YWx1ZXMgZm9yIHRoZSBlYXJseSBzZWFzb24gS2V5IExhcmdvIGNvcGVwb2RzIHdlcmUgY29sbGVjdGVkIGF0IHRoZSBlbmQgb2YgRmVicnVhcnkgMjAyMyBhcyBwYXJ0IG9mIGEgc2VwYXJhdGUgcHJvamVjdC4gQm9keSBzaXplIHZhbHVlcyB3ZXJlIG5vdCBtZWFzdXJlZCBkdXJpbmcgdGhpcyBwcm9qZWN0LCBub3Igd2VyZSBjb3BlcG9kcyBpbmRpdmlkdWFsbHkgcHJlc2VydmVkIGFmdGVyIHRoZSBleHBlcmltZW50cy4gVGhlc2UgZWFybHkgc2Vhc29uIENUbWF4IHZhbHVlcyBhcmUgaW5jbHVkZWQgYXMgYSBwb2ludCBvZiBjb21wYXJpc29uLiBJbmRpdmlkdWFsIG1lYXN1cmVtZW50cyBhcmUgc2hvd24gaW4gc21hbGwgcG9pbnRzIGZvciBlYWNoIGNvbGxlY3Rpb24uIFRoZSBsYXJnZSBwb2ludHMgaW5kaWNhdGUgdGhlIG1lYW4gdmFsdWVzIGZvciBlYWNoIGNvbGxlY3Rpb24uIAoKYGBge3Igc2Vhc29uYWwtY3QtbWF4fQptZWFuX2N0bWF4ID0gZnVsbF9kYXRhICU+JSAKICBncm91cF9ieShzaXRlLCBzZWFzb24sIGRveSwgY29sbGVjdGlvbl90ZW1wKSAlPiUgCiAgc3VtbWFyaXplKG1lYW5fY3RtYXggPSBtZWFuKGN0bWF4KSwKICAgICAgICAgICAgbWVkaWFuX2N0bWF4ID0gbWVkaWFuKGN0bWF4KSkKCmN0bWF4X3Bsb3QgPSBnZ3Bsb3QoZnVsbF9kYXRhLCBhZXMoeCA9IHNlYXNvbiwgeSA9IGN0bWF4LCBjb2xvdXIgPSBzaXRlKSkgKyAKICBnZW9tX2xpbmUoZGF0YSA9IG1lYW5fY3RtYXgsIAogICAgICAgICAgICBhZXMoeSA9IG1lYW5fY3RtYXgsIGdyb3VwID0gc2l0ZSksCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjQpLAogICAgICAgICAgICBsaW5ld2lkdGggPSAxKSArIAogIGdlb21fcG9pbnQocG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXJkb2RnZShqaXR0ZXIud2lkdGggPSAwLjEsIGppdHRlci5oZWlnaHQgPSAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2RnZS53aWR0aCA9IDAuNCksCiAgICAgICAgICAgICBhbHBoYSA9IDAuMykgKyAKICBnZW9tX3BvaW50KGRhdGEgPSBtZWFuX2N0bWF4LCAKICAgICAgICAgICAgIGFlcyh5ID0gbWVhbl9jdG1heCksCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC40KSwKICAgICAgICAgICAgIHNpemUgPSA0KSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2l0ZV9jb2xzKSArIAogIGxhYnMoeSA9ICJDVG1heCAowrBDKSIsCiAgICAgICB4ID0gIlNlYXNvbiIpICsKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLCAKICAgICAgICBsZWdlbmQudGl0bGUuYWxpZ24gPSAwLjEyNSkKCmN0bWF4X3Bsb3QKYGBgCgpgYGB7ciBkb3ktY3QtbWF4LCBpbmNsdWRlID0gRn0KIyBUaGUgc2FtZSBkYXRhIGlzIHNob3duIGJlbG93LCBwbG90dGVkIGFnYWluc3QgZGF5IG9mIHRoZSB5ZWFyIGluc3RlYWQgb2Ygc2Vhc29uLiBUaGlzIGFjY291bnRzIGZvciB0aGUgdmFyaWFibGUgdGltaW5nIG9mIGNvbGxlY3Rpb25zIGFjcm9zcyByZWdpb25zIChlLmcuIC0gdGhlIGNvbXByZXNzZWQgY29sbGVjdGlvbnMgZnJvbSB0aGUgTm9ydGhlcm4gc2l0ZXMgdG8gYWNjb21vZGF0ZSB0aGUgZWFybGllciBvbnNldCBvZiBjb2xkIHRlbXBlcmF0dXJlcykuIAoKZ2dwbG90KGZpbHRlcihmdWxsX2RhdGEsIHNpdGUgIT0gIktleSBMYXJnbyIpLCBhZXMoeCA9IGRveSwgeSA9IGN0bWF4LCBjb2xvdXIgPSBzaXRlKSkgKyAKICBnZW9tX2xpbmUoZGF0YSA9IGZpbHRlcihtZWFuX2N0bWF4LCBzaXRlICE9ICJLZXkgTGFyZ28iKSwgCiAgICAgICAgICAgIGFlcyh5ID0gbWVkaWFuX2N0bWF4LCBncm91cCA9IHNpdGUpLAogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC40KSwKICAgICAgICAgICAgbGluZXdpZHRoID0gMSkgKyAKICBnZW9tX3BvaW50KHBvc2l0aW9uID0gCiAgICAgICAgICAgICAgIHBvc2l0aW9uX2ppdHRlcmRvZGdlKAogICAgICAgICAgICAgICAgIGppdHRlci53aWR0aCA9IDAuMSwgCiAgICAgICAgICAgICAgICAgaml0dGVyLmhlaWdodCA9IDAsCiAgICAgICAgICAgICAgICAgZG9kZ2Uud2lkdGggPSAwLjQpLAogICAgICAgICAgICAgYWxwaGEgPSAwLjMpICsgCiAgZ2VvbV9wb2ludChkYXRhID0gZmlsdGVyKG1lYW5fY3RtYXgsIHNpdGUgIT0gIktleSBMYXJnbyIpLCAKICAgICAgICAgICAgIGFlcyh5ID0gbWVkaWFuX2N0bWF4KSwKICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjQpLAogICAgICAgICAgICAgc2l6ZSA9IDQpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgeGxpbSgxODAsMzUwKSArIAogIGxhYnMoeSA9ICJDVG1heCAowrBDKSIsCiAgICAgICB4ID0gIkRheSBvZiB0aGUgWWVhciIpICsKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLCAKICAgICAgICBsZWdlbmQudGl0bGUuYWxpZ24gPSAwLjEyNSkKYGBgCgpgYGB7ciBjdG1heC1pbmQtcG9wcy1kb3ksIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTYsIGluY2x1ZGUgPSBGfQojIENUbWF4IGRhdGEgZm9yIGVhY2ggaW5kaXZpZHVhbCBzaXRlIGlzIHNob3duIGJlbG93LCBwbG90dGVkIGFnYWluc3QgZGF5IG9mIHRoZSB5ZWFyLiAKCmdncGxvdChmaWx0ZXIoZnVsbF9kYXRhLCBzaXRlICE9ICJLZXkgTGFyZ28iKSwgCiAgICAgICBhZXMoeCA9IGRveSwgeSA9IGN0bWF4LCBjb2xvdXIgPSBzaXRlKSkgKyAKICBmYWNldF93cmFwKC5+c2l0ZSwgc2NhbGVzID0gImZyZWUiKSArIAogIGdlb21fbGluZShkYXRhID0gZmlsdGVyKG1lYW5fY3RtYXgsIHNpdGUgIT0gIktleSBMYXJnbyIpLCAKICAgICAgICAgICAgYWVzKHkgPSBtZWFuX2N0bWF4LCBncm91cCA9IHNpdGUpLAogICAgICAgICAgICBsaW5ld2lkdGggPSAzLCBhbHBoYSA9IDAuNSkgKyAKICBnZW9tX3BvaW50KGFscGhhID0gMC44KSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2l0ZV9jb2xzKSArIAogIGxhYnMoeSA9ICJDVG1heCAowrBDKSIsCiAgICAgICB4ID0gIkRheSBvZiBZZWFyIikgKwogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgCiAgICAgICAgbGVnZW5kLnRpdGxlLmFsaWduID0gMC4xMjUsCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMjAsIGhqdXN0ID0gMCwgdmp1c3QgPSAwLjUpKQpgYGAKCmBgYHtyIGN0bWF4LWluZC1wb3BzLXNlYXNvbiwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9NiwgaW5jbHVkZSA9IEZ9CmdncGxvdChmdWxsX2RhdGEsIGFlcyh4ID0gc2Vhc29uLCB5ID0gY3RtYXgsIGNvbG91ciA9IHNpdGUpKSArIAogIGZhY2V0X3dyYXAoLn5zaXRlLCBzY2FsZXMgPSAiZnJlZV95IikgKyAKICBnZW9tX2xpbmUoZGF0YSA9IG1lYW5fY3RtYXgsIAogICAgICAgICAgICBhZXMoeSA9IG1lZGlhbl9jdG1heCwgZ3JvdXAgPSBzaXRlKSwKICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuNCksCiAgICAgICAgICAgIGxpbmV3aWR0aCA9IDMsIGFscGhhID0gMC41KSArIAogIGdlb21fbGluZShkYXRhID0gbWVhbl9jdG1heCwgCiAgICAgICAgICAgIGFlcyh5ID0gY29sbGVjdGlvbl90ZW1wLCBncm91cCA9IHNpdGUpLAogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC40KSwKICAgICAgICAgICAgbGluZXdpZHRoID0gMiwKICAgICAgICAgICAgY29sb3VyID0gImdyZXkiKSArIAogIGdlb21fcG9pbnQocG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXJkb2RnZShqaXR0ZXIud2lkdGggPSAwLjEsIGppdHRlci5oZWlnaHQgPSAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2RnZS53aWR0aCA9IDAuNCksCiAgICAgICAgICAgICBhbHBoYSA9IDAuOCkgKyAKICAjIGdlb21fcG9pbnQoZGF0YSA9IG1lYW5fY3RtYXgsIAogICMgICAgICAgICAgICBhZXMoeSA9IG1lZGlhbl9jdG1heCksCiAgIyAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjQpLAogICMgICAgICAgICAgICBzaXplID0gNCkgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgKyAKICBsYWJzKHkgPSAiQ1RtYXggKMKwQykiLAogICAgICAgeCA9ICJTZWFzb24iKSArCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCAKICAgICAgICBsZWdlbmQudGl0bGUuYWxpZ24gPSAwLjEyNSkKYGBgCgojIyMgV2FybWluZyB0b2xlcmFuY2UKCldhcm1pbmcgdG9sZXJhbmNlICh0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZXJtYWwgbGltaXRzIGFuZCBlbnZpcm9ubWVudGFsIHRlbXBlcmF0dXJlcykgaXMgYSBjb21tb25seSB1c2VkIG1ldHJpYyBvZiBjbGltYXRlIHZ1bG5lcmFiaWxpdHkuIFdlIGNhbGN1bGF0ZWQgdGhpcyBhcyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIG1lYXN1cmVkIENUbWF4IHZhbHVlcyBhbmQgdGhlIGNvbGxlY3Rpb24gdGVtcGVyYXR1cmUuIFNtYWxsZXIgd2FybWluZyB0b2xlcmFuY2UgdmFsdWVzIGluZGljYXRlIHRoYXQgcG9wdWxhdGlvbnMgd2VyZSBuZWFyZXIgdG8gdGhlaXIgdXBwZXIgdGhlcm1hbCBsaW1pdHMsIGFuZCBtYXkgdGhlcmVmb3JlIGJlIG1vcmUgdnVsbmVyYWJsZSB0byBhZGRpdGlvbmFsIHdhcm1pbmcuIAoKYGBge3Igc2Vhc29uYWwtd2FybWluZy10b2x9Cm1lYW5fd3QgPSBmdWxsX2RhdGEgJT4lIAogIGdyb3VwX2J5KHNpdGUsIHNlYXNvbikgJT4lIAogIHN1bW1hcml6ZShtZWFuX3d0ID0gbWVhbih3YXJtaW5nX3RvbCksCiAgICAgICAgICAgIG1lZGlhbl93dCA9IG1lZGlhbih3YXJtaW5nX3RvbCkpCgpnZ3Bsb3QoZnVsbF9kYXRhLCBhZXMoeCA9IHNlYXNvbiwgeSA9IHdhcm1pbmdfdG9sLCBjb2xvdXIgPSBzaXRlKSkgKyAKICBnZW9tX2xpbmUoZGF0YSA9IG1lYW5fd3QsIAogICAgICAgICAgICBhZXMoeSA9IG1lYW5fd3QsIGdyb3VwID0gc2l0ZSksCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjQpLAogICAgICAgICAgICBsaW5ld2lkdGggPSAxKSArIAogIGdlb21fcG9pbnQocG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXJkb2RnZShqaXR0ZXIud2lkdGggPSAwLjEsIGppdHRlci5oZWlnaHQgPSAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2RnZS53aWR0aCA9IDAuNCksCiAgICAgICAgICAgICBhbHBoYSA9IDAuMykgKyAKICBnZW9tX3BvaW50KGRhdGEgPSBtZWFuX3d0LCAKICAgICAgICAgICAgIGFlcyh5ID0gbWVhbl93dCksCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC40KSwKICAgICAgICAgICAgIHNpemUgPSA0KSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2l0ZV9jb2xzKSArIAogIGxhYnMoeSA9ICJXYXJtaW5nIFRvbGVyYW5jZSAowrBDKSIsCiAgICAgICB4ID0gIlNlYXNvbiIpICsKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLCAKICAgICAgICBsZWdlbmQudGl0bGUuYWxpZ24gPSAwLjEyNSkKYGBgCgojIyMgQm9keSBTaXplCgpGb2xsb3dpbmcgdGhlIENUbWF4IGFzc2F5LCBpbmRpdmlkdWFscyB3ZXJlIHBob3RvZ3JhcGhlZCBmb3IgYm9keSBzaXplIG1lYXN1cmVtZW50cy4gUHJvc29tZSBsZW5ndGhzIHdlcmUgbWVhc3VyZWQgZnJvbSB0aGVzZSBwaG90b2dyYXBocyB1c2luZyBhIHNjYWxlIG1pY3JvbWV0ZXIgYW5kIHRoZSBzb2Z0d2FyZSBJbWFnZUouIFRoZXNlIG1lYXN1cmVtZW50cyBhcmUgc2hvd24gYmVsb3cuIEFzIGJlZm9yZSwgbGFyZ2UgcG9pbnRzIGluZGljYXRlIHRoZSBtZWFuIGJvZHkgc2l6ZS4gV2hpbGUgbGVzcyBjb2hlc2l2ZSB0aGFuIENUbWF4LCBhIGdlbmVyYWwgdHJlbmQgb2YgaW5jcmVhc2luZyBib2R5IHNpemUgd2l0aCBsYXRpdHVkZSBhbmQgdGltZSBvZiB5ZWFyIGNhbiBiZSBzZWVuLiAKCmBgYHtyIHNlYXNvbmFsLWJvZHktc2l6ZX0KbWVhbl9zaXplID0gZnVsbF9kYXRhICU+JSAKICBncm91cF9ieShzaXRlLCBzZWFzb24sIGRveSwgY29sbGVjdGlvbl90ZW1wKSAlPiUgCiAgc3VtbWFyaXplKG1lYW5fc2l6ZSA9IG1lYW4oc2l6ZSksCiAgICAgICAgICAgIG1lZGlhbl9zaXplID0gbWVkaWFuKHNpemUpKQoKZ2dwbG90KGZ1bGxfZGF0YSwgYWVzKHggPSBzZWFzb24sIHkgPSBzaXplLCBjb2xvdXIgPSBzaXRlKSkgKyAKICBnZW9tX2xpbmUoZGF0YSA9IG1lYW5fc2l6ZSwgCiAgICAgICAgICAgIGFlcyh5ID0gbWVhbl9zaXplLCBncm91cCA9IHNpdGUpLAogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC40KSwKICAgICAgICAgICAgbGluZXdpZHRoID0gMSkgKyAKICBnZW9tX3BvaW50KHBvc2l0aW9uID0gcG9zaXRpb25faml0dGVyZG9kZ2Uoaml0dGVyLndpZHRoID0gMC4xLCBqaXR0ZXIuaGVpZ2h0ID0gMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9kZ2Uud2lkdGggPSAwLjQpLAogICAgICAgICAgICAgYWxwaGEgPSAwLjMpICsgCiAgZ2VvbV9wb2ludChkYXRhID0gbWVhbl9zaXplLCAKICAgICAgICAgICAgIGFlcyh5ID0gbWVhbl9zaXplKSwKICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjQpLAogICAgICAgICAgICAgc2l6ZSA9IDQpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh5ID0gIlByb3NvbWUgTGVuZ3RoIChtbSkiLAogICAgICAgeCA9ICJTZWFzb24iKSArCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwgCiAgICAgICAgbGVnZW5kLnRpdGxlLmFsaWduID0gMC4xMjUpCmBgYAoKYGBge3IgZG95LWJvZHktc2l6ZSwgaW5jbHVkZSA9IEZ9CmdncGxvdChkcm9wX25hKGZ1bGxfZGF0YSwgc2l6ZSksIGFlcyh4ID0gZG95LCB5ID0gc2l6ZSwgY29sb3VyID0gc2l0ZSkpICsgCiAgZ2VvbV9saW5lKGRhdGEgPSBkcm9wX25hKG1lYW5fc2l6ZSwgbWVhbl9zaXplKSwgCiAgICAgICAgICAgIGFlcyh5ID0gbWVkaWFuX3NpemUsIGdyb3VwID0gc2l0ZSksCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjQpLAogICAgICAgICAgICBsaW5ld2lkdGggPSAxKSArIAogIGdlb21fcG9pbnQocG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXJkb2RnZShqaXR0ZXIud2lkdGggPSAwLjEsIGppdHRlci5oZWlnaHQgPSAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2RnZS53aWR0aCA9IDAuNCksCiAgICAgICAgICAgICBhbHBoYSA9IDAuMykgKyAKICBnZW9tX3BvaW50KGRhdGEgPSBkcm9wX25hKG1lYW5fc2l6ZSwgbWVhbl9zaXplKSwgCiAgICAgICAgICAgICBhZXMoeSA9IG1lZGlhbl9zaXplKSwKICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjQpLAogICAgICAgICAgICAgc2l6ZSA9IDQpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh5ID0gIlByb3NvbWUgTGVuZ3RoIChtbSkiLAogICAgICAgeCA9ICJEYXkgb2YgdGhlIFllYXIiKSArCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwgCiAgICAgICAgbGVnZW5kLnRpdGxlLmFsaWduID0gMC4xMjUpCmBgYAoKCmBgYHtyIHNpemUtaW5kLXBvcHMtZG95LCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD02LCBpbmNsdWRlID0gRn0KIyBTaG93biBiZWxvdyBpcyB0aGUgYm9keSBzaXplIGRhdGEgZm9yIGVhY2ggaW5kaXZpZHVhbCBzaXRlLiAKCmdncGxvdChkcm9wX25hKGZ1bGxfZGF0YSwgc2l6ZSksIGFlcyh4ID0gZG95LCB5ID0gc2l6ZSwgY29sb3VyID0gc2l0ZSkpICsgCiAgZmFjZXRfd3JhcCgufnNpdGUpICsgCiAgZ2VvbV9saW5lKGRhdGEgPSBkcm9wX25hKG1lYW5fc2l6ZSwgbWVhbl9zaXplKSwgCiAgICAgICAgICAgIGFlcyh5ID0gbWVhbl9zaXplLCBncm91cCA9IHNpdGUpLAogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC40KSwKICAgICAgICAgICAgbGluZXdpZHRoID0gMywgYWxwaGEgPSAwLjUpICsgCiAgZ2VvbV9wb2ludChwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcmRvZGdlKGppdHRlci53aWR0aCA9IDAuMSwgaml0dGVyLmhlaWdodCA9IDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvZGdlLndpZHRoID0gMC40KSwKICAgICAgICAgICAgIGFscGhhID0gMC44KSArIAogICMgZ2VvbV9wb2ludChkYXRhID0gbWVhbl9jdG1heCwgCiAgIyAgICAgICAgICAgIGFlcyh5ID0gbWVkaWFuX2N0bWF4KSwKICAjICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuNCksCiAgIyAgICAgICAgICAgIHNpemUgPSA0KSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2l0ZV9jb2xzKSArIAogIGxhYnMoeSA9ICJQcm9zb21lIExlbmd0aCAobW0pIiwKICAgICAgIHggPSAiRGF5IG9mIFllYXIiKSArCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCAKICAgICAgICBsZWdlbmQudGl0bGUuYWxpZ24gPSAwLjEyNSkKYGBgCgpgYGB7ciBzaXplLWluZC1wb3BzLXNlYXNvbiwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9NiwgaW5jbHVkZSA9IEZ9CmdncGxvdChmdWxsX2RhdGEsIGFlcyh4ID0gc2Vhc29uLCB5ID0gc2l6ZSwgY29sb3VyID0gc2l0ZSkpICsgCiAgZmFjZXRfd3JhcCgufnNpdGUpICsgCiAgZ2VvbV9saW5lKGRhdGEgPSBtZWFuX3NpemUsIAogICAgICAgICAgICBhZXMoeSA9IG1lZGlhbl9zaXplLCBncm91cCA9IHNpdGUpLAogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC40KSwKICAgICAgICAgICAgbGluZXdpZHRoID0gMywgYWxwaGEgPSAwLjUpICsgCiAgZ2VvbV9wb2ludChwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcmRvZGdlKGppdHRlci53aWR0aCA9IDAuMSwgaml0dGVyLmhlaWdodCA9IDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvZGdlLndpZHRoID0gMC40KSwKICAgICAgICAgICAgIGFscGhhID0gMC44KSArIAogICMgZ2VvbV9wb2ludChkYXRhID0gbWVhbl9jdG1heCwgCiAgIyAgICAgICAgICAgIGFlcyh5ID0gbWVkaWFuX2N0bWF4KSwKICAjICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuNCksCiAgIyAgICAgICAgICAgIHNpemUgPSA0KSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2l0ZV9jb2xzKSArIAogIGxhYnMoeSA9ICJQcm9zb21lIExlbmd0aCAobW0pIiwKICAgICAgIHggPSAiU2Vhc29uIikgKwogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgCiAgICAgICAgbGVnZW5kLnRpdGxlLmFsaWduID0gMC4xMjUpCmBgYAoKIyMjIFNhbGluaXR5IFBhaXIgQ29tcGFyaXNvbnMgCgpUaGUgdGhyZWUgcGFpcnMgb2YgY3Jvc3Mtc2FsaW5pdHkgY29tcGFyaXNvbnMgZG8gc2hvdyBldmlkZW5jZSBmb3IgZmluZS1zY2FsZSB0cmFpdCBkaXZlcmdlbmNlLCBhbHRob3VnaCB0aGVyZSB3YXMgbm8gY29uc2lzdGVudCBwYXR0ZXJuIGluIHRoZSBkaXJlY3Rpb24gb3IgbWFnbml0dWRlIG9mIGRpZmZlcmVuY2VzLiBDVG1heCB3YXMgc2ltaWxhciBhY3Jvc3Mgc2l0ZXMgaW4gdGhlIFNvdXRoZXJuIGFuZCBDZW50cmFsIHBhaXJzLiBJbiB0aGUgTm9ydGhlcm4gcGFpciwgQ1RtYXggdGVuZGVkIHRvIGJlIHNsaWdodGx5IGxvd2VyIGZvciBpbmRpdmlkdWFscyBmcm9tIHRoZSBsb3cgc2FsaW5pdHkgc2l0ZS4gU2l6ZSB3YXMgbW9yZSB2YXJpYWJsZSBiZXR3ZWVuIHRoZSBwYWlyZWQgc2l0ZXMuIEluIHRoZSBTb3V0aCwgbG93IHNhbGluaXR5IGluZGl2aWR1YWxzIHdlcmUgY29uc2lzdGVudGx5IHNtYWxsZXIgdGhhbiBoaWdoIHNhbGluaXR5IGluZGl2aWR1YWxzLCBkZXNwaXRlIGV4cGVyaWVuY2luZyBzaW1pbGFyIHRlbXBlcmF0dXJlcy4gSW4gdGhlIENlbnRyYWwgcGFpciwgaW5kaXZpZHVhbHMgZnJvbSB0aGUgbG93IHNhbGluaXR5IHNpdGUgdGVuZGVkIHRvIGJlIHNsaWdodGx5IGxhcmdlciB0aGFuIHRob3NlIGZyb20gdGhlIGhpZ2ggc2FsaW5pdHkgc2l0ZSwgYWx0aG91Z2ggdGhpcyB2YXJpZWQgc2Vhc29uYWxseS4gU2l6ZXMgdGVuZGVkIHRvIGJlIG1vcmUgc2ltaWxhciBhY3Jvc3MgdGhlIGNvbGxlY3Rpb25zIGZyb20gdGhlIE5vcnRoZXJuIHBhaXIuIAoKYGBge3Igc2FsLXBhaXItdHJhaXRzfQpzYWxfY29tcF9jdG1heF9wbG90ID0gc2FsX2NvbXBzICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzYWxpbml0eSwgeSA9IGN0bWF4LCBjb2xvdXIgPSBzZWFzb24sIGdyb3VwID0gc2Vhc29uKSkgKyAKICBmYWNldF93cmFwKHJlZ2lvbn4uKSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDIsCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC4yKSkgKyAKICAjZ2VvbV9saW5lKHNpemUgPSAxLjUpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzZWFzb25fY29scykgKyAKICBsYWJzKHkgPSAiQ1RtYXggKMKwQykiLAogICAgICAgeCA9ICIiKSArIAogIHRoZW1lX21hdHRfZmFjZXRzKGJhc2Vfc2l6ZSA9IDE0KQoKc2FsX2NvbXBfc2l6ZV9wbG90ID0gc2FsX2NvbXBzICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzYWxpbml0eSwgeSA9IHNpemUsIGNvbG91ciA9IHNlYXNvbiwgZ3JvdXAgPSBzZWFzb24pKSArIAogIGZhY2V0X3dyYXAocmVnaW9ufi4pICsgCiAgZ2VvbV9wb2ludChzaXplID0gMiwgCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC4yKSkgKyAKICAjZ2VvbV9saW5lKHNpemUgPSAxLjUpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzZWFzb25fY29scykgKyAKICBsYWJzKHkgPSAiUHJvc29tZSBMZW5ndGggKG1tKSIsCiAgICAgICB4ID0gIiIpICsgCiAgdGhlbWVfbWF0dF9mYWNldHMoYmFzZV9zaXplID0gMTQpCgpnZ2FycmFuZ2Uoc2FsX2NvbXBfY3RtYXhfcGxvdCwgc2FsX2NvbXBfc2l6ZV9wbG90LCBucm93ID0gMiwgY29tbW9uLmxlZ2VuZCA9IFQsIGxlZ2VuZCA9ICJyaWdodCIpCgojIyMKIyAKIyBzYWxfY29tcF9jdG1heC5tb2RlbCA9IGxtKGN0bWF4IH4gY29sbGVjdGlvbl90ZW1wLCBkYXRhID0gc2FsX2NvbXBzKQojICMgc3VtbWFyeShjdG1heF90ZW1wLm1vZGVsKQojICMgY2FyOjpBbm92YShjdG1heF90ZW1wLm1vZGVsKQojIHNhbF9jb21wX2N0bWF4X3Jlc2lkcyA9IHJlc2lkdWFscyhzYWxfY29tcF9jdG1heC5tb2RlbCkKIyAKIyBzYWxfY29tcF9zaXplLm1vZGVsID0gbG0oc2l6ZSB+IGNvbGxlY3Rpb25fdGVtcCwgZGF0YSA9IHNhbF9jb21wcykKIyAjIHN1bW1hcnkoc2l6ZV90ZW1wLm1vZGVsKQojICMgY2FyOjpBbm92YShzaXplX3RlbXAubW9kZWwpCiMgc2FsX2NvbXBfc2l6ZV9yZXNpZHMgPSByZXNpZHVhbHMoc2FsX2NvbXBfc2l6ZS5tb2RlbCkKIyAKIyBzYWxfY29tcF9jdG1heF9yZXNpZF9wbG90ID0gc2FsX2NvbXBzICU+JQojICAgbXV0YXRlKGN0bWF4X3Jlc2lkcyA9IHNhbF9jb21wX2N0bWF4X3Jlc2lkcywKIyAgICAgICAgICBzaXplX3Jlc2lkcyA9IHNhbF9jb21wX3NpemVfcmVzaWRzKSAlPiUKIyAgIGdncGxvdChhZXMoeCA9IHNhbGluaXR5LCB5ID0gY3RtYXhfcmVzaWRzLCBjb2xvdXIgPSBzZWFzb24sIGdyb3VwID0gc2Vhc29uKSkgKwojICAgZmFjZXRfd3JhcChyZWdpb25+LikgKwojICAgZ2VvbV9wb2ludChzaXplID0gMiwKIyAgICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuNSkpICsKIyAgICNnZW9tX2xpbmUoc2l6ZSA9IDEuNSkgKwojICAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzZWFzb25fY29scykgKwojICAgbGFicyh5ID0gIkNUbWF4IFxuUmVzaWR1YWxzIiwKIyAgICAgICAgeCA9ICIiKSArCiMgICB0aGVtZV9tYXR0X2ZhY2V0cyhiYXNlX3NpemUgPSAxNCkKIyAKIyBzYWxfY29tcF9zaXplX3Jlc2lkX3Bsb3QgPSBzYWxfY29tcHMgJT4lCiMgICBtdXRhdGUoY3RtYXhfcmVzaWRzID0gc2FsX2NvbXBfY3RtYXhfcmVzaWRzLAojICAgICAgICAgIHNpemVfcmVzaWRzID0gc2FsX2NvbXBfc2l6ZV9yZXNpZHMpICU+JQojICAgZ2dwbG90KGFlcyh4ID0gc2FsaW5pdHksIHkgPSBzaXplX3Jlc2lkcywgY29sb3VyID0gc2Vhc29uLCBncm91cCA9IHNlYXNvbikpICsKIyAgIGZhY2V0X3dyYXAocmVnaW9ufi4pICsKIyAgIGdlb21fcG9pbnQoc2l6ZSA9IDIsCiMgICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjUpKSArCiMgICAjZ2VvbV9saW5lKHNpemUgPSAxLjUpICsKIyAgIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2Vhc29uX2NvbHMpICsKIyAgIGxhYnMoeSA9ICJQcm9zb21lIExlbmd0aCBcblJlc2lkdWFscyIsCiMgICAgICAgIHggPSAiIikgKwojICAgdGhlbWVfbWF0dF9mYWNldHMoYmFzZV9zaXplID0gMTQpCiMgCiMgZ2dhcnJhbmdlKHNhbF9jb21wX2N0bWF4X3Jlc2lkX3Bsb3QsIHNhbF9jb21wX3NpemVfcmVzaWRfcGxvdCwgbnJvdyA9IDIsIGNvbW1vbi5sZWdlbmQgPSBULCBsZWdlbmQgPSAicmlnaHQiKQpgYGAKCiMjIFRyYWl0IENvcnJlbGF0aW9ucwoKUmVnYXJkbGVzcyBvZiB0aGUgdW5kZXJseWluZyBtZWNoYW5pc20gKGdlbmV0aWMgZGlmZmVyZW50aWF0aW9uIG9yIHBoZW5vdHlwaWMgcGxhc3RpY2l0eSksIHdlIGV4cGVjdCB0aGF0IGNvbGxlY3Rpb25zIGZyb20gd2FybWVyIHdhdGVycyBzaG91bGQgeWllbGQgY29wZXBvZHMgd2l0aCBoaWdoZXIgdGhlcm1hbCBsaW1pdHMgYW5kIHNtYWxsZXIgYm9keSBzaXplcy4gT3VyIG9ic2VydmF0aW9ucyBsYXJnZWx5IGZpdCB0aGlzIGV4cGVjdGF0aW9uLCB3aXRoIHN0cm9uZyBpbmNyZWFzZXMgaW4gQ1RtYXggYXQgaGlnaGVyIHRlbXBlcmF0dXJlcywgYW5kIGEgZ2VuZXJhbCBkZWNyZWFzZSBpbiBwcm9zb21lIGxlbmd0aHMgYXMgdGVtcGVyYXR1cmUgaW5jcmVhc2VkLiBUaGVyZSB3YXMgYSBsYXJnZXIgY29ycmVsYXRpb24gYmV0d2VlbiBDVG1heCBhbmQgdGVtcGVyYXR1cmUgdGhhbiBzaXplIGFuZCB0ZW1wZXJhdHVyZS4gVGhlcmUgYXJlIG15cmlhZCByZWFzb25zIHRoaXMgbWlnaHQgYmUgb2JzZXJ2ZWQsIGJ1dCBvbmUgcG90ZW50aWFsIGlzIHRoZSBwb3RlbnRpYWwgZm9yIGFjY2xpbWF0aW9uIG9mIHRoZXJtYWwgbGltaXRzLiBCb2R5IHNpemUgaXMgZml4ZWQgaW4gdGhlIGFkdWx0IHN0YWdlLCB3aGlsZSBDVG1heCBjYW4gY29udGludWUgdG8gdmFyeSBhcyB3YXRlciB0ZW1wZXJhdHVyZSBjaGFuZ2VzLiBUaGlzIGlzIGluZGlyZWN0IGV2aWRlbmNlIGZvciB0aGUgaW1wb3J0YW5jZSBvZiByYXBpZCBhY2NsaW1hdGlvbiBpbiB0aGUgb2JzZXJ2ZWQgcGF0dGVybnMuIAoKYGBge3IgdGVtcC1jb3JzLCBmaWcud2lkdGg9MTUsIGZpZy5oZWlnaHQ9Nn0KY3RtYXhfdGVtcF9wbG90ID0gZ2dwbG90KGZ1bGxfZGF0YSwgYWVzKHggPSBjb2xsZWN0aW9uX3RlbXAsIHkgPSBjdG1heCkpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBULAogICAgICAgICAgICAgIGxpbmV3aWR0aCA9IDIsIAogICAgICAgICAgICAgIGNvbG91ciA9ICJncmV5IikgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBzaXRlKSwgCiAgICAgICAgICAgICBzaXplID0gMiwgYWxwaGEgPSAwLjcpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh5ID0gIkNUbWF4ICjCsEMpIiwKICAgICAgIHggPSAiQ29sbGVjdGlvbiBUZW1wLiAowrBDKSIpICsKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCgpzaXplX3RlbXBfcGxvdCA9IGdncGxvdChmdWxsX2RhdGEsIGFlcyh4ID0gY29sbGVjdGlvbl90ZW1wLCB5ID0gc2l6ZSkpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBULAogICAgICAgICAgICAgIGxpbmV3aWR0aCA9IDIsIAogICAgICAgICAgICAgIGNvbG91ciA9ICJncmV5IikgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBzaXRlKSwgCiAgICAgICAgICAgICBzaXplID0gMiwgYWxwaGEgPSAwLjcpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh5ID0gIlByb3NvbWUgTGVuZ3RoIChtbSkiLAogICAgICAgeCA9ICJDb2xsZWN0aW9uIFRlbXAuICjCsEMpIikgKwogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgp3dF90ZW1wX3Bsb3QgPSBnZ3Bsb3QoZnVsbF9kYXRhLCBhZXMoeCA9IGNvbGxlY3Rpb25fdGVtcCwgeSA9IHdhcm1pbmdfdG9sKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IFQsCiAgICAgICAgICAgICAgbGluZXdpZHRoID0gMiwgCiAgICAgICAgICAgICAgY29sb3VyID0gImdyZXkiKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG91ciA9IHNpdGUpLCAKICAgICAgICAgICAgIHNpemUgPSAyLCBhbHBoYSA9IDAuNykgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgKyAKICBsYWJzKHkgPSAiV2FybWluZyBUb2xlcmFuY2UgKMKwQykiLAogICAgICAgeCA9ICJDb2xsZWN0aW9uIFRlbXAuICjCsEMpIikgKwogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgpnZ2FycmFuZ2UoY3RtYXhfdGVtcF9wbG90LCB3dF90ZW1wX3Bsb3QsIHNpemVfdGVtcF9wbG90LCBjb21tb24ubGVnZW5kID0gVCwgbGVnZW5kID0gImJvdHRvbSIsIG5yb3cgPSAxKQpgYGAKCmBgYHtyIHBvcC10ZW1wLWNvcnMsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTYsIGluY2x1ZGUgPSBGfQojIFNob3duIGJlbG93IGFyZSB0aGVzZSB0ZW1wZXJhdHVyZSBjb3JyZWxhdGlvbnMgZm9yIGVhY2ggaW5kaXZpZHVhbCBwb3B1bGF0aW9uLiBWYXJpYXRpb24gaW4gdGhlIHRlbXBlcmF0dXJlIHNlbnNpdGl2aXR5IG9mIHRoZXNlIHRyYWl0cyBhcHBlYXJzIHRvIHZhcnkgYWNyb3NzIHBvcHVsYXRpb25zLCB3aXRoIHJlZHVjZWQgc2xvcGVzIGluIGJvdGggdGhlIGxvd2VzdCBhbmQgdGhlIGhpZ2hlc3QgbGF0aXR1ZGUgcG9wdWxhdGlvbnMuIEFnYWluLCB3ZSBlbXBoYXNpemUgdGhhdCB0aGlzIG9ic2VydmVkIHRyYWl0IHZhcmlhdGlvbiBtYXkgc3RlbSBmcm9tIGVpdGhlciAob3IgYm90aCkgcGxhc3RpYyBhbmQgZ2VuZXRpYyBlZmZlY3RzLiBIb3dldmVyLCB0aGVzZSBvYnNlcnZhdGlvbnMgcHJvdmlkZSBlc3RpbWF0ZXMgZm9yIHJlYWxpc3RpYyBwYXR0ZXJucyBpbiB0ZW1wZXJhdHVyZSBzZW5zaXRpdml0eSBmb3IgdGhlc2UgcG9wdWxhdGlvbnMuIAoKZ2dwbG90KGZ1bGxfZGF0YSwgYWVzKHggPSBjb2xsZWN0aW9uX3RlbXAsIHkgPSBjdG1heCkpICsgCiAgZmFjZXRfd3JhcCgufnNpdGUpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBULAogICAgICAgICAgICAgIGxpbmV3aWR0aCA9IDIsIAogICAgICAgICAgICAgIGNvbG91ciA9ICJncmV5IikgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBzaXRlKSwgCiAgICAgICAgICAgICBzaXplID0gMiwgYWxwaGEgPSAwLjcpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh5ID0gIkNUbWF4ICjCsEMpIiwKICAgICAgIHggPSAiQ29sbGVjdGlvbiBUZW1wLiAowrBDKSIpICsKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCgpnZ3Bsb3QoZnVsbF9kYXRhLCBhZXMoeCA9IGNvbGxlY3Rpb25fdGVtcCwgeSA9IHNpemUpKSArIAogIGZhY2V0X3dyYXAoLn5zaXRlKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gVCwKICAgICAgICAgICAgICBsaW5ld2lkdGggPSAyLCAKICAgICAgICAgICAgICBjb2xvdXIgPSAiZ3JleSIpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gc2l0ZSksIAogICAgICAgICAgICAgc2l6ZSA9IDIsIGFscGhhID0gMC43KSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2l0ZV9jb2xzKSArIAogIGxhYnMoeSA9ICJQcm9zb21lIExlbmd0aCAobW0pIiwKICAgICAgIHggPSAiQ29sbGVjdGlvbiBUZW1wLiAowrBDKSIpICsKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCgpgYGAKCk9uZSBhZGRpdGlvbmFsIGNvcnJlbGF0aW9uIG9mIGludGVyZXN0IGlzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBwcm9zb21lIGxlbmd0aCBhbmQgQ1RtYXguIEluIG1hbnkgY2FzZXMsIGxhcmdlciBib2R5IHNpemVzIGFyZSBhc3NvY2lhdGVkIHdpdGggY29sZCBhZGFwdGF0aW9uL2FjY2xpbWF0aW9uLCBhbmQgdGhlcmUgaXMgYSBnZW5lcmFsIHRyZW5kIG9mIGRlY3JlYXNpbmcgdGhlcm1hbCBsaW1pdHMgd2l0aCBpbmNyZWFzaW5nIHNpemUuIFNob3duIGJlbG93IGlzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBwcm9zb21lIGxlbmd0aCBhbmQgQ1RtYXggaW4gb3VyIGRhdGEgc2V0LiBJbmRpdmlkdWFsIHJlZ3Jlc3Npb24gbGluZXMgZm9yIGVhY2ggc2l0ZSBhcmUgYWxzbyBpbmNsdWRlZCAtIHRoZSBkYXJrIGdyZXkgbGluZXMgaW4gdGhlIGJhY2tncm91bmQgcmVwcmVzZW50IHRoZSAndW5pdmVyc2FsJyByZWdyZXNzaW9uIGZvciB0aGF0IHNpdGUsIHdpdGggaW5kaXZpZHVhbCBjb2xvcmVkIHJlZ3Jlc3Npb24gbGluZXMgZm9yIGVhY2ggY29sbGVjdGlvbi4gQWNyb3NzIG91ciBjb2xsZWN0aW9ucywgd2Ugc2VlIGV2aWRlbmNlIGZvciB0aGlzIHJlbGF0aW9uc2hpcCwgd2l0aCBsYXJnZXIgaW5kaXZpZHVhbHMgaGF2aW5nIGxvd2VyIHRoZXJtYWwgbGltaXRzLiAgICAgIAoKYGBge3IgY3RtYXgtdnMtc2l6ZSwgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9MTB9CnVuaXZlcnNhbF9zaXplID0gZnVsbF9kYXRhICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzaXplLCB5ID0gY3RtYXgpKSArIAogICMgZ2VvbV9zbW9vdGgoZGF0YSA9IGZpbHRlcihmdWxsX2RhdGEsIGN0bWF4ID4gMzEpLCAKICAjICAgICAgICAgICAgIGFlcyh4ID0gc2l6ZSwgeSA9IGN0bWF4KSwKICAjICAgICAgICAgICAgIG1ldGhvZCA9ICJsbSIsIAogICMgICAgICAgICAgICAgY29sb3VyID0gImdyZXk2MCIsIAogICMgICAgICAgICAgICAgc2UgPSBGLAogICMgICAgICAgICAgICAgbGluZXdpZHRoID0gMikgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IFQsCiAgICAgICAgICAgICAgbGluZXdpZHRoID0gMiwKICAgICAgICAgICAgICBjb2xvdXIgPSAiZ3JleTcwIikgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBzaXRlKSwKICAgICAgICAgICAgIHNpemUgPSAyLCBhbHBoYSA9IDAuNykgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgKyAKICBsYWJzKHkgPSAiQ1RtYXggKMKwQykiLAogICAgICAgeCA9ICIiKSArCiAgdGhlbWVfbWF0dChiYXNlX3NpemUgPSAxNCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLAogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSkKCnBvcF9zaXplID0gZnVsbF9kYXRhICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzaXplLCB5ID0gY3RtYXgsIGNvbG91ciA9IHNpdGUsIGdyb3VwID0gc2Vhc29uKSkgKyAKICBmYWNldF93cmFwKHNpdGV+LikgKyAKICAjIGdlb21fc21vb3RoKGRhdGEgPSBmaWx0ZXIoZnVsbF9kYXRhLCBjdG1heCA+IDMxKSwgCiAgIyAgICAgICAgICAgICBhZXMoeCA9IHNpemUsIHkgPSBjdG1heCksCiAgIyAgICAgICAgICAgICBtZXRob2QgPSAibG0iLCAKICAjICAgICAgICAgICAgIGNvbG91ciA9ICJncmV5NjAiLCAKICAjICAgICAgICAgICAgIHNlID0gRiwKICAjICAgICAgICAgICAgIGxpbmV3aWR0aCA9IDIpICsgCiAgZ2VvbV9zbW9vdGgoZGF0YSA9IGZ1bGxfZGF0YSwgCiAgICAgICAgICAgICAgYWVzKHggPSBzaXplLCB5ID0gY3RtYXgsIGdyb3VwID0gc2l0ZSksIAogICAgICAgICAgICAgIGNvbG91ciA9ICJncmV5MjAiLCBtZXRob2QgPSAibG0iLCBzZSA9IEYpICsgCiAgZ2VvbV9wb2ludChzaXplID0gMS4zLCBhbHBoYSA9IDAuMykgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEYsCiAgICAgICAgICAgICAgbGluZXdpZHRoID0gMSkgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgKyAKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gYygwLjYsIDAuOCwgMSkpICsgCiAgbGFicyh5ID0gIkNUbWF4ICjCsEMpIiwKICAgICAgIHggPSAiUHJvc29tZSBMZW5ndGggKG1tKSIpICsKICB0aGVtZV9tYXR0KGJhc2Vfc2l6ZSA9IDE0KSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgpnZ2FycmFuZ2UodW5pdmVyc2FsX3NpemUsIHBvcF9zaXplLCBjb21tb24ubGVnZW5kID0gVCwgbGVnZW5kID0gIm5vbmUiLCBucm93ID0gMikKYGBgCgpUaGlzIHJlbGF0aW9uc2hpcCBtYXkgYmUgYWZmZWN0ZWQgYnkgY2hhbmdlcyBpbiB0ZW1wZXJhdHVyZSBhdCBlYWNoIHNpdGUsIGhvd2V2ZXIsIHdoaWNoIGNhbiBhZmZlY3QgYm90aCBib2R5IHNpemUgYW5kIHRoZXJtYWwgbGltaXRzLiBJZiB0aGVyZSBpcyBhIHRydWUgbWVjaGFuaXN0aWMgcmVsYXRpb25zaGlwIGJldHdlZW4gYm9keSBzaXplIGFuZCB0aGVybWFsIGxpbWl0cywgd2Ugd291bGQgZXhwZWN0IHRvIHNlZSB0aGlzIHJlbGF0aW9uc2hpcCBlbWVyZ2UgKip3aXRoaW4qKiBwb3B1bGF0aW9ucywgb3IgZXZlbiBpbmRpdmlkdWFsIGNvbGxlY3Rpb25zLiBTaG93biBiZWxvdyBpcyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gQ1RtYXggYW5kIHNpemUgcmVzaWR1YWxzLCBhY3F1aXJlZCBmcm9tIHJlZ3Jlc3Npb25zIG9mIHRoZXNlIHRyYWl0cyBhZ2FpbnN0IGNvbGxlY3Rpb24gdGVtcGVyYXR1cmUuIFRoaXMgc3Vic3RhbnRpYWxseSByZWR1Y2VzIHRoZSBzdHJlbmd0aCBvZiB0aGUgYXBwYXJlbnQgcmVsYXRpb25zaGlwLCBidXQgdGhlcmUgaXMgc3RpbGwgYSBzbGlnaHRseSBuZWdhdGl2ZSBvdmVyYWxsIHJlbGF0aW9uc2hpcCwgc3Bhbm5pbmcgYm90aCBhY3Jvc3MtcG9wdWxhdGlvbiwgd2l0aGluLXBvcHVsYXRpb24sIGFuZCBldmVuIHdpdGhpbi1jb2xsZWN0aW9uIHNjYWxlcyAoc2VlIHRoZSBTYXd5ZXIgUGFyayBjb2xsZWN0aW9ucywgZm9yIGV4YW1wbGUpLiAgICAgCgpgYGB7ciBjdG1heC12cy1zaXplLXJlc2lkcywgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9MTB9CmZpbHRlcmVkX2RhdGEgPSBmdWxsX2RhdGEgJT4lIAogIGRyb3BfbmEoc2l6ZSwgY3RtYXgpICU+JSAKICBtdXRhdGUodGVtcF9jZW50ID0gc2NhbGUoY29sbGVjdGlvbl90ZW1wLCBzY2FsZSA9IEYpLAogICAgICAgICBzaXplX2NlbnQgPSBzY2FsZShzaXplLCBzY2FsZSA9IEYpLAogICAgICAgICBzYWxfY2VudCA9IHNjYWxlKGNvbGxlY3Rpb25fc2FsaW5pdHksIHNjYWxlID0gRiksCiAgICAgICAgIHNhbF90eXBlID0gaWZfZWxzZShjb2xsZWN0aW9uX3NhbGluaXR5ID4gMjAsICJIaWdoIiwgIkxvdyIpKQoKY3RtYXhfdGVtcC5tb2RlbCA9IGxtKGN0bWF4IH4gY29sbGVjdGlvbl90ZW1wICsgc2l0ZSwgZGF0YSA9IGZpbHRlcmVkX2RhdGEpCmN0bWF4X3Jlc2lkcyA9IHJlc2lkdWFscyhjdG1heF90ZW1wLm1vZGVsKQoKc2l6ZV90ZW1wLm1vZGVsID0gbG0oc2l6ZSB+IGNvbGxlY3Rpb25fdGVtcCArIHNpdGUsIGRhdGEgPSBmaWx0ZXJlZF9kYXRhKQpzaXplX3Jlc2lkcyA9IHJlc2lkdWFscyhzaXplX3RlbXAubW9kZWwpCgp1bml2ZXJzYWxfcmVzaWRzID0gZmlsdGVyZWRfZGF0YSAlPiUgCiAgbXV0YXRlKGN0bWF4X3Jlc2lkcyA9IGN0bWF4X3Jlc2lkcywKICAgICAgICAgc2l6ZV9yZXNpZHMgPSBzaXplX3Jlc2lkcykgCgphbGxfcmVzaWRzID0gZ2dwbG90KHVuaXZlcnNhbF9yZXNpZHMsIGFlcyh4ID0gc2l6ZV9yZXNpZHMsIHkgPSBjdG1heF9yZXNpZHMpKSArIAogICMgZ2VvbV9zbW9vdGgoZGF0YSA9IGZpbHRlcihmdWxsX2RhdGEsIGN0bWF4ID4gMzEpLCAKICAjICAgICAgICAgICAgIGFlcyh4ID0gc2l6ZSwgeSA9IGN0bWF4KSwKICAjICAgICAgICAgICAgIG1ldGhvZCA9ICJsbSIsIAogICMgICAgICAgICAgICAgY29sb3VyID0gImdyZXk2MCIsIAogICMgICAgICAgICAgICAgc2UgPSBGLAogICMgICAgICAgICAgICAgbGluZXdpZHRoID0gMikgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IFQsCiAgICAgICAgICAgICAgbGluZXdpZHRoID0gMiwKICAgICAgICAgICAgICBjb2xvdXIgPSAiZ3JleTcwIikgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBzaXRlKSwKICAgICAgICAgICAgIHNpemUgPSAyLCBhbHBoYSA9IDAuNykgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgKyAKICBsYWJzKHkgPSAiQ1RtYXggUmVzaWR1YWxzIiwKICAgICAgIHggPSAiIikgKwogIHRoZW1lX21hdHQoYmFzZV9zaXplID0gMTQpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwKICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCkpCgpwb3BfcmVzaWRzID0gZ2dwbG90KHVuaXZlcnNhbF9yZXNpZHMsIGFlcyh4ID0gc2l6ZV9yZXNpZHMsIHkgPSBjdG1heF9yZXNpZHMsIGNvbG91ciA9IHNpdGUsIGdyb3VwID0gc2Vhc29uKSkgKyAKICBmYWNldF93cmFwKHNpdGV+LikgKyAKICAjIGdlb21fc21vb3RoKGRhdGEgPSBmaWx0ZXIoZnVsbF9kYXRhLCBjdG1heCA+IDMxKSwgCiAgIyAgICAgICAgICAgICBhZXMoeCA9IHNpemUsIHkgPSBjdG1heCksCiAgIyAgICAgICAgICAgICBtZXRob2QgPSAibG0iLCAKICAjICAgICAgICAgICAgIGNvbG91ciA9ICJncmV5NjAiLCAKICAjICAgICAgICAgICAgIHNlID0gRiwKICAjICAgICAgICAgICAgIGxpbmV3aWR0aCA9IDIpICsgCiAgZ2VvbV9zbW9vdGgoYWVzKHggPSBzaXplX3Jlc2lkcywgeSA9IGN0bWF4X3Jlc2lkcywgZ3JvdXAgPSBzaXRlKSwgCiAgICAgICAgICAgICAgY29sb3VyID0gImdyZXkyMCIsIG1ldGhvZCA9ICJsbSIsIHNlID0gRikgKyAKICBnZW9tX3BvaW50KHNpemUgPSAxLjMsIGFscGhhID0gMC4zKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRiwKICAgICAgICAgICAgICBsaW5ld2lkdGggPSAxKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2l0ZV9jb2xzKSArIAogIGxhYnMoeSA9ICJDVG1heCBSZXNpZHVhbHMiLAogICAgICAgeCA9ICJQcm9zb21lIExlbmd0aCBSZXNpZHVhbHMiKSArCiAgdGhlbWVfbWF0dChiYXNlX3NpemUgPSAxNCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQoKZ2dhcnJhbmdlKGFsbF9yZXNpZHMsIHBvcF9yZXNpZHMsIGNvbW1vbi5sZWdlbmQgPSBULCBsZWdlbmQgPSAibm9uZSIsIG5yb3cgPSAyKQpgYGAKCmBgYHtyIGN0bWF4LW1vZGVsLCBpbmNsdWRlID0gRn0KY3RtYXgubW9kZWwgPSBsbWU0OjpsbWVyKAogIGRhdGEgPSBmaWx0ZXJlZF9kYXRhLCAKICBjdG1heCB+IHRlbXBfY2VudCArIHNpemUgKyBzYWxfdHlwZSArICgxICsgdGVtcF9jZW50fHNpdGUpICsgKDF8c2Vhc29uKSkKYGBgCgpUbyBtb3JlIGZvcm1hbGx5IHRlc3QgdGhlIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiBDVG1heCwgY29sbGVjdGlvbiB0ZW1wZXJhdHVyZSwgYW5kIHNpemUsIHdlIHVzZWQgYSBsaW5lYXIgbWl4ZWQgZWZmZWN0cyBtb2RlbCwgc3RydWN0dXJlZCBhcyBgY3RtYXggfiBjb2xsZWN0aW9uIHRlbXAuICsgc2l6ZSArIHNhbGluaXR5ICsgKDEgKyBjb2xsZWN0aW9uIHRlbXAufHNpdGUpYC4gVGhpcyBleGFtaW5lcyB0aGUgZWZmZWN0cyBvZiB0ZW1wZXJhdHVyZSBhbmQgc2l6ZSBvbiBDVG1heCwgYWxvbmcgd2l0aCBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRoZSBzYWxpbml0eSBncm91cGluZ3MuIENvbGxlY3Rpb24gdGVtcGVyYXR1cmUgYW5kIHNpemUgd2VyZSBib3RoIGNlbnRlcmVkIGFuZCBzYWxpbml0eSB0cmFuc2Zvcm1lZCBpbnRvIGEgY2F0ZWdvcmljYWwgdmFyaWFibGUgKCJsb3ciIHNhbGluaXR5IGFzIGFueXRoaW5nIGJlbG93IDIwIHBzdSwgImhpZ2giIHNhbGluaXR5IGFzIGFueXRoaW5nIGFib3ZlIDIwIHBzdSkgYmVmb3JlIG1vZGVsIGZpdHRpbmcuIFRoZSBtb2RlbCBhbHNvIGluY2x1ZGVzIHJhbmRvbSBpbnRlcmNlcHRzIGZvciBlYWNoIHNpdGUgYW5kIHJhbmRvbSBzbG9wZXMgZm9yIGNvbGxlY3Rpb24gdGVtcGVyYXR1cmUgKGkuZS4gLSB2YXJpYXRpb24gaW4gdGhlIGFjY2xpbWF0aW9uIGNhcGFjaXR5IG9mIENUbWF4KS4gQSByYW5kb20gaW50ZXJjZXB0IGZvciBzZWFzb24gaXMgYWxzbyBpbmNsdWRlZC4gCgpDb2xsZWN0aW9uIHRlbXBlcmF0dXJlIGFuZCBib2R5IHNpemUgYm90aCBoYWQgYSBzaWduaWZpY2FudCBlZmZlY3Qgb24gQ1RtYXgsIGJ1dCBzYWxpbml0eSB0eXBlIGRpZCBub3QuIFRoZSBvdmVyYWxsIGVmZmVjdCBvZiB0ZW1wZXJhdHVyZSBzdWdnZXN0cyBhbiBpbmNyZWFzZSBpbiBDVG1heCBvZiBgciByb3VuZCh1bm5hbWUoZml4ZWYoY3RtYXgubW9kZWwpWyJ0ZW1wX2NlbnQiXSksIGRpZ2l0cyA9IDIpYMKwQyBwZXIgwrBDIGluY3JlYXNlIGluIGNvbGxlY3Rpb24gdGVtcGVyYXR1cmUgKGkuZS4gLSBhbiBBUlIgdmFsdWUgb2YgYHIgcm91bmQodW5uYW1lKGZpeGVmKGN0bWF4Lm1vZGVsKVsidGVtcF9jZW50Il0pLCBkaWdpdHMgPSAyKWApLCB3aGlsZSBpbmNyZWFzaW5nIGJvZHkgc2l6ZXMgZGVjcmVhc2UgQ1RtYXggYnkgYHIgcm91bmQodW5uYW1lKGZpeGVmKGN0bWF4Lm1vZGVsKVsic2l6ZSJdKSwgZGlnaXRzID0gMilgwrBDIHBlciBtbSAob3IgYSBkZWNyZWFzZSBvZiB+YHIgcm91bmQodW5uYW1lKGZpeGVmKGN0bWF4Lm1vZGVsKVsic2l6ZSJdKSwgZGlnaXRzID0gMikvMTBgwrBDIHBlciB0ZW50aCBvZiBhIG1tLCB3aGljaCBpcyBtb3JlIGJpb2xvZ2ljYWxseSByZWFsaXN0aWMgZm9yICpBLiB0b25zYSopLiBXaGlsZSBub3Qgc2lnbmlmaWNhbnQsIHRoZSBtb2RlbCBzdWdnZXN0cyBsb3cgc2FsaW5pdHkgc2l0ZXMgaGFkIGxvd2VyIHRoZXJtYWwgbGltaXRzIGJ5IH5gciBhYnMocm91bmQodW5uYW1lKGZpeGVmKGN0bWF4Lm1vZGVsKVsic2FsX3R5cGVMb3ciXSksIGRpZ2l0cyA9IDEpKWDCsEMuCgpgYGB7cn0KCmVmZmVjdHNfc3VtbWFyeSA9IGRhdGEuZnJhbWUoCiAgIlRlbXBlcmF0dXJlIiA9IHVubmFtZShmaXhlZihjdG1heC5tb2RlbClbInRlbXBfY2VudCJdKSwKICAiU2l6ZSIgPSB1bm5hbWUoZml4ZWYoY3RtYXgubW9kZWwpWyJzaXplIl0pLAogICJTYWxpbml0eSIgPSB1bm5hbWUoZml4ZWYoY3RtYXgubW9kZWwpWyJzYWxfdHlwZUxvdyJdKSkgJT4lICAKICBzZWxlY3QoIlRlbXBlcmF0dXJlIChwZXIgZGVncmVlKSIgPSBUZW1wZXJhdHVyZSwgCiAgICAgICAgICJTaXplIChwZXIgbW0pIiA9IFNpemUsIAogICAgICAgICAiU2FsaW5pdHkgKExvdyB2cy4gSGlnaCkiID0gU2FsaW5pdHkpCgprbml0cjo6a2FibGUoZWZmZWN0c19zdW1tYXJ5KQpgYGAKCkJ5IGV4dHJhY3RpbmcgdGhlIGNvbmRpdGlvbmFsIG1vZGUgZm9yIHRoZSByYW5kb20gZWZmZWN0cywgd2UgY2FuIGFsc28gZXhhbWluZSBob3cgdGhlcm1hbCBsaW1pdHMgdmFyeSBhY3Jvc3Mgc2l0ZXMgYmV5b25kIHRoZSBpbmZsdWVuY2Ugb2YgY29sbGVjdGlvbiB0ZW1wZXJhdHVyZXMgYW5kIGJvZHkgc2l6ZXMuIFNob3duIGJlbG93IGFyZSB0aGVzZSAicG9wdWxhdGlvbiIgdmFsdWVzIChlc3NlbnRpYWxseSwgYWxsIGVsc2UgYmVpbmcgZXF1YWwsIGhvdyB3b3VsZCB0aGVybWFsIGxpbWl0IHZhcnkgYWNyb3NzIHBvcHVsYXRpb25zKS4gV2UgY2FuIHNlZSB0aGF0LCBzaW1pbGFyIHRvIHdoYXQncyBiZWVuIG9ic2VydmVkIGluIGNvbW1vbiBnYXJkZW4gZXhwZXJpbWVudHMgd2l0aCAqQS4gdG9uc2EqIHByZXZpb3VzbHksIHNpZ25pZmljYW50IGRpdmVyZ2VuY2VzIGFyZSBwcmVzZW50IGF0IG9ubHkgYSBmZXcgc2l0ZXMgbmVhciB0aGUgbGF0aXR1ZGluYWwgZXh0cmVtZXMsIHdpdGggRm9ydCBIYW1lciBhbmQgUml0Y2hpZSBXaGFyZiBoYXZpbmcgaW5jcmVhc2VkIGFuZCBkZWNyZWFzZWQgdGhlcm1hbCBsaW1pdHMgcmVzcGVjdGl2ZWx5LiBJbnRlcmVzdGluZ2x5LCBib3RoIG9mIHRoZXNlIHNpdGVzIHdlcmUgbG93IHNhbGluaXR5IHNpdGVzLCBhbHNvIGluIGxpbmUgd2l0aCBwcmV2aW91cyByZXN1bHRzIHN1Z2dlc3RpbmcgZ2VuZSBmbG93IGJldHdlZW4gaGlnaCBzYWxpbml0eSBzaXRlcyBtYXkgY29uc3RyYWluIGRpZmZlcmVudGlhdGlvbi4gCgpgYGB7ciBwb3AtZWZmcy1wbG90LCBmaWcud2lkdGg9OSwgZmlnLmhlaWdodD02fQpwb3BfZWZmcyA9IFJFc2ltKGN0bWF4Lm1vZGVsKSAlPiUgCiAgZHBseXI6OnNlbGVjdCgic2l0ZSIgPSBncm91cElELCB0ZXJtLCBtZWFuLCBzZCkgJT4lIAogIGZpbHRlcih0ZXJtID09ICIoSW50ZXJjZXB0KSIpICU+JSAKICBpbm5lcl9qb2luKHNpdGVfZGF0YSwgYnkgPSBjKCJzaXRlIikpICU+JSAKICBtdXRhdGUoc2l0ZSA9IGZjdF9yZW9yZGVyKHNpdGUsIGxhdCkpCgpzZWFzb25fZWZmcyA9IFJFc2ltKGN0bWF4Lm1vZGVsKSAlPiUgCiAgZHBseXI6OnNlbGVjdCgic2l0ZSIgPSBncm91cElELCB0ZXJtLCBtZWFuLCBzZCkgJT4lIAogIGZpbHRlcihzaXRlICVpbiUgYygiZWFybHkiLCAicGVhayIsICJsYXRlIikpICU+JSAKICBzZWxlY3QoInNlYXNvbiIgPSBzaXRlLCBtZWFuLCBzZCkKCiNwbG90UkVzaW0oUkVzaW0oY3RtYXgubW9kZWwpKSAgIyBwbG90IHRoZSBpbnRlcnZhbCBlc3RpbWF0ZXMKCnBvcF9lZmZzX3Bsb3QgPSBnZ3Bsb3QocG9wX2VmZnMsIGFlcyh4ID0gbGF0LCB5ID0gbWVhbiwgY29sb3VyID0gc2l0ZSkpICsgCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgY29sb3VyID0gImdyZXkiKSArCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IG1lYW4gLSAxLjk2ICogc2QsIHltYXggPSBtZWFuICsgMS45NiAqIHNkKSwKICAgICAgICAgICAgICAgIHdpZHRoID0gMC41LCBsaW5ld2lkdGggPSAxKSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDMpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh4ID0gIkxhdGl0dWRlIiwgCiAgICAgICB5ID0gIlBvcHVsYXRpb24gRWZmZWN0IikgKyAKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQoKcG9wX2VmZnNfcGxvdApgYGAKCkZpbmFsbHksIHNob3duIGJlbG93IGFyZSB0aGUgZXN0aW1hdGVkIHJhbmRvbSBzbG9wZXMgZm9yIGVhY2ggc2l0ZS4gVGhlc2UgcmVwcmVzZW50IHRoZSBlZmZlY3RzIG9mIGNvbGxlY3Rpb24gdGVtcGVyYXR1cmUgb24gQ1RtYXggZm9yIGVhY2ggc2l0ZS4gSW50ZXJlc3RpbmdseSwgdGhlc2UgZXN0aW1hdGVzIGRpdmVyZ2UgZnJvbSB0aGUgcmVzdWx0cyBvZiBwcmV2aW91cyBjb21tb24gZ2FyZGVuIGV4cGVyaW1lbnRzLCB3aGljaCBzaG93ZWQgdGhlIHN0cm9uZ2VzdCBwbGFzdGljaXR5IGluIGhpZ2ggbGF0aXR1ZGUgc2l0ZXMuIEhlcmUsIGFjY2xpbWF0aW9uIGFwcGVhcnMgdG8gcGVhayBpbiBtaWQtbGF0aXR1ZGVzLCBhbmQgZGVjcmVhc2UgYXQgYm90aCBoaWdoIGFuZCBsb3cgbGF0aXR1ZGUgc2l0ZXMuIFRoaXMgc3VnZ2VzdHMgZmFjdG9ycyBtYXkgY29uc3RyYWluIGFjY2xpbWF0aW9uIGNhcGFjaXR5IGluIG5hdHVyYWwgcG9wdWxhdGlvbnMgKGUuZy4gZm9vZCBhdmFpbGFiaWxpdHksIGVudmlyb25tZW50YWwgdmFyaWF0aW9uLCBwYXRob2dlbnMsIGV0Yy4pLiAKCmBgYHtyIHNpdGUtYXJyLXBsb3QsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTR9CmNvZWZmaWNpZW50cyhjdG1heC5tb2RlbCkkc2l0ZSAlPiUKICBqYW5pdG9yOjpjbGVhbl9uYW1lcygpICU+JQogIHJvd25hbWVzX3RvX2NvbHVtbih2YXIgPSAic2l0ZSIpICU+JQogIGlubmVyX2pvaW4oc2l0ZV9kYXRhKSAlPiUgCiAgbXV0YXRlKHNpdGUgPSBmY3RfcmVvcmRlcihzaXRlLCBsYXQpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gdGVtcF9jZW50LCB5ID0gc2l0ZSkpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBzaXRlKSwKICAgICAgICAgICAgIHNpemUgPSA1KSArCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsKICBsYWJzKHggPSAiQVJSIikgKyAKICB0aGVtZV9tYXR0KCkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwKICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCkpCmBgYAoKIyMgVHJhaXQgVmFyaWFiaWxpdHkKClNob3duIGJlbG93IGlzIHRoZSB0cmFpdCB2YXJpYXRpb24gKHJhbmdlcykgZm9yIGVhY2ggc2l0ZS4gUmFuZ2VzIGFyZSBjYWxjdWxhdGVkIGZvciBlYWNoIGNvbGxlY3Rpb24gc2VwYXJhdGVseS4gCgpgYGB7ciB0cmFpdC1yYW5nZS1wbG90LCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9NC41fQp0cmFpdF9yYW5nZXMgPSBmdWxsX2RhdGEgJT4lIAogIGdyb3VwX2J5KHNpdGUsIHNlYXNvbiwgY29sbGVjdGlvbl90ZW1wLCBjb2xsZWN0aW9uX3NhbGluaXR5LCBkb3ksIGxhdCkgJT4lIAogIHN1bW1hcmlzZShtZWFuX2N0bWF4ID0gbWVhbihjdG1heCksCiAgICAgICAgICAgIGN0bWF4X3JhbmdlID0gbWF4KGN0bWF4KSAtIG1pbihjdG1heCksCiAgICAgICAgICAgIGN0bWF4X3ZhciA9IHZhcihjdG1heCksCiAgICAgICAgICAgIG1lYW5fc2l6ZSA9IG1lYW4oc2l6ZSksCiAgICAgICAgICAgIHNpemVfcmFuZ2UgPSBtYXgoc2l6ZSkgLSBtaW4oc2l6ZSksCiAgICAgICAgICAgIHNpemVfdmFyID0gdmFyKHNpemUpKSAlPiUgCiAgbXV0YXRlKHByb3BfY3RtYXhfcmFuZ2UgPSBjdG1heF9yYW5nZSAvIG1lYW5fY3RtYXgsCiAgICAgICAgIHByb3Bfc2l6ZV9yYW5nZSA9IHNpemVfcmFuZ2UgLyBtZWFuX3NpemUpCgpjdG1heF9yYW5nZV90ZW1wID0gZ2dwbG90KHRyYWl0X3JhbmdlcywgYWVzKHggPSBjb2xsZWN0aW9uX3RlbXAsIHkgPSBjdG1heF9yYW5nZSkpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgY29sb3VyID0gImJsYWNrIikgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBzaXRlKSwgCiAgICAgICAgICAgICBzaXplID0gMykgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgKyAKICBsYWJzKHkgPSAiQ1RtYXggUmFuZ2UgKMKwQykiLAogICAgICAgeCA9ICJDb2xsZWN0aW9uIFRlbXAuICjCsEMpIikgKwogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgpjdG1heF92YXJfdGVtcCA9IGdncGxvdCh0cmFpdF9yYW5nZXMsIGFlcyh4ID0gY29sbGVjdGlvbl90ZW1wLCB5ID0gY3RtYXhfdmFyLCBjb2xvdXIgPSBzaXRlKSkgKyAKICBnZW9tX3BvaW50KHNpemUgPSAzKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2l0ZV9jb2xzKSArIAogIGxhYnMoeSA9ICJDVG1heCBSYW5nZSAowrBDKSIsCiAgICAgICB4ID0gIkNvbGxlY3Rpb24gVGVtcC4gKMKwQykiKSArCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKCnNpemVfcmFuZ2VfdGVtcCA9IGdncGxvdCh0cmFpdF9yYW5nZXMsIGFlcyh4ID0gY29sbGVjdGlvbl90ZW1wLCB5ID0gc2l6ZV9yYW5nZSwgY29sb3VyID0gc2l0ZSkpICsgCiAgZ2VvbV9wb2ludChzaXplID0gMykgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgKyAKICBsYWJzKHkgPSAiU2l6ZSBSYW5nZSAobW0pIiwKICAgICAgIHggPSAiQ29sbGVjdGlvbiBUZW1wLiAowrBDKSIpICsKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQoKc2l6ZV92YXJfdGVtcCA9IGdncGxvdCh0cmFpdF9yYW5nZXMsIGFlcyh4ID0gY29sbGVjdGlvbl90ZW1wLCB5ID0gc2l6ZV92YXIsIGNvbG91ciA9IHNpdGUpKSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDMpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh5ID0gIlNpemUgUmFuZ2UgKG1tKSIsCiAgICAgICB4ID0gIkNvbGxlY3Rpb24gVGVtcC4gKMKwQykiKSArCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKCmdnYXJyYW5nZShjdG1heF9yYW5nZV90ZW1wLCBzaXplX3JhbmdlX3RlbXAsIGNvbW1vbi5sZWdlbmQgPSBULCBsZWdlbmQgPSAicmlnaHQiKQpgYGAKCkNoYW5nZXMgaW4gdHJhaXQgdmFyaWFuY2UgbWF5IGJlIGluZGljYXRpdmUgb2YgcGhlbm90eXBpYyBzZWxlY3Rpb24uIElmIHNlbGVjdGlvbiAoYXMgb3Bwb3NlZCB0byBhY2NsaW1hdGlvbikgYXJlIGRyaXZpbmcgc2Vhc29uYWwgY2hhbmdlcywgd2UgbWF5IGV4cGVjdCB0byBzZWUgYSByZWR1Y3Rpb24gaW4gdmFyaWFuY2UgaW4gdGhlIHBlYWsgc2FtcGxlcyByZWxhdGl2ZSB0byB0aGUgZWFybHkgc2Vhc29uIHNhbXBsZXMuIE5vdGUgdGhhdCBlYXJseSBzZWFzb24gY29sbGVjdGlvbiB0ZW1wZXJhdHVyZXMgdGhpcyB5ZWFyIHdlcmUgaGlnaGVyIHRoYW4gZXhwZWN0ZWQsIGRyaXZlbiBieSBmYWlybHkgc3Ryb25nIGhlYXR3YXZlcyBhY3Jvc3MgdGhlIE5vcnRoIEF0bGFudGljLiBBcyBzaG93biBpbiB0aGUgdGVtcGVyYXR1cmUgcHJvZmlsZXMgZm9yIGVhY2ggc2l0ZSwgdGhlICdlYXJseScgc2FtcGxlcyB3ZXJlIGNvbGxlY3RlZCBqdXN0IGFmdGVyIGhpZ2ggdGVtcGVyYXR1cmVzIHdlcmUgcmVhY2hlZCwgd2hpbGUgJ3BlYWsnIHNhbXBsZXMgd2VyZSBjb2xsZWN0ZWQgYWZ0ZXIgc2l0ZXMgaGFkIGV4cGVyaWVuY2VkIGhpZ2ggdGVtcGVyYXR1cmVzIGZvciBzZXZlcmFsIHdlZWtzIChnZW5lcmF0aW9ucykuIEFzIHdhcm1pbmcgdG9sZXJhbmNlcyB3ZXJlIGZhaXJseSBoaWdoIHRocm91Z2hvdXQgdGhpcyBwZXJpb2QsIHdlIHdpbGwgYXNzdW1lIHRoYXQgc2VsZWN0aW9uIHdhcyB3ZWFrIGJlZm9yZSB0aGUgZWFybHkgc2FtcGxlcy4gSWYgdGhlIGVhcmx5IG9uc2V0IG9mIGhpZ2ggdGVtcGVyYXR1cmVzIGZpbHRlcmVkIG91dCB2dWxuZXJhYmxlIGdlbm90eXBlcyBwcmlvciB0byBvdXIgc2FtcGxpbmcsIHRoZSByZXN1bHRzIHdpbGwgYmUgYSBjb25zZXJ2YXRpdmUgZXN0aW1hdGUgb2YgdGhlIGVmZmVjdHMgb2Ygc2VsZWN0aW9uIG9uIHRyYWl0IHZhcmlhbmNlLiAgICAgCgpTaG93biBiZWxvdyBpcyB0aGUgc2Vhc29uYWwgcHJvZ3Jlc3Npb24gb2YgdmFyaWFuY2UgaW4gQ1RtYXggZm9yIGVhY2ggc2l0ZS4gRm9yIG1hbnkgc2l0ZXMsIHZhcmlhbmNlIGRlY3JlYXNlZCBiZXR3ZWVuIHRoZSBlYXJseSBhbmQgcGVhayBzYW1wbGVzLCBhbmQgdGhlbiBpbmNyZWFzZWQgYWdhaW4gaW4gdGhlIGxhdGUgc2FtcGxlLiBGb3Igc29tZSBzaXRlcyAoZS5nLiBFc2tlciBQb2ludCksIHRoaXMgaW5jcmVhc2UgaW4gdGhlIGxhdGUgc2FtcGxlIHdhcyBzdWJzdGFudGlhbC4gCgpgYGB7ciBzZWFzb24tdmFyfQpnZ3Bsb3QodHJhaXRfcmFuZ2VzLCBhZXMoeCA9IHNlYXNvbiwgeSA9IGN0bWF4X3ZhciwgY29sb3VyID0gc2l0ZSkpICsgCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IHNpdGUpLCAKICAgICAgICAgICAgbGluZXdpZHRoID0gMS41KSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDMpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh5ID0gIkNUbWF4IFZhcmlhbmNlIiwKICAgICAgIHggPSAiU2Vhc29uIikgKwogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsIAogICAgICAgIGxlZ2VuZC50aXRsZS5hbGlnbiA9IDAuMTI1KQpgYGAKClNob3duIGJlbG93IGlzIHRoZSBzZWFzb25hbCBwcm9ncmVzc2lvbiBvZiB2YXJpYW5jZSBpbiBib2R5IHNpemUuIEEgc2ltaWxhciBwYXR0ZXJuIG9mIGRlY3JlYXNpbmcgdmFyaWFuY2UgaW4gcGVhayBzYW1wbGVzIHJlbGF0aXZlIHRvIGVhcmx5IGFuZCBsYXRlIHNhbXBsZXMgaXMgYWdhaW4gc2VlbiBmb3IgbWFueSBzaXRlcy4gVGhlIG9idmlvdXMgZXhjZXB0aW9uIGlzIHRoZSBFc2tlciBQb2ludCBzYW1wbGUsIHdoaWNoIHNhdyB0aGUgb3Bwb3NpdGUgdHJlbmQuIAoKYGBge3J9CmdncGxvdCh0cmFpdF9yYW5nZXMsIGFlcyh4ID0gc2Vhc29uLCB5ID0gc2l6ZV92YXIsIGNvbG91ciA9IHNpdGUpKSArIAogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBzaXRlKSwgCiAgICAgICAgICAgIGxpbmV3aWR0aCA9IDEuNSkgKyAKICBnZW9tX3BvaW50KHNpemUgPSAzKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2l0ZV9jb2xzKSArIAogIGxhYnMoeSA9ICJDVG1heCBWYXJpYW5jZSIsCiAgICAgICB4ID0gIlNlYXNvbiIpICsKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLCAKICAgICAgICBsZWdlbmQudGl0bGUuYWxpZ24gPSAwLjEyNSkKYGBgCgpTaG93biBiZWxvdyBhcmUgdGhlIHNlYXNvbmFsIGNoYW5nZXMgaW4gdHJhaXQgdmFyaWFuY2UgZm9yIGVhY2ggc2l0ZSBpbmRpdmlkdWFsbHkuIAoKYGBge3IgdmFyLWluZC1wb3BzLXNlYXNvbiwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9Nn0KZ2dwbG90KHRyYWl0X3JhbmdlcywgYWVzKHggPSBzZWFzb24sIHkgPSBjdG1heF92YXIsIGNvbG91ciA9IHNpdGUpKSArIAogIGZhY2V0X3dyYXAoc2l0ZX4uKSArIAogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBzaXRlKSwgCiAgICAgICAgICAgIGxpbmV3aWR0aCA9IDEuNSkgKyAKICBnZW9tX3BvaW50KHNpemUgPSAzKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2l0ZV9jb2xzKSArIAogIGxhYnMoeSA9ICJDVG1heCBWYXJpYW5jZSIsCiAgICAgICB4ID0gIlNlYXNvbiIpICsKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsIAogICAgICAgIGxlZ2VuZC50aXRsZS5hbGlnbiA9IDAuMTI1KQoKZ2dwbG90KHRyYWl0X3JhbmdlcywgYWVzKHggPSBzZWFzb24sIHkgPSBzaXplX3ZhciwgY29sb3VyID0gc2l0ZSkpICsgCiAgZmFjZXRfd3JhcChzaXRlfi4pICsgCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IHNpdGUpLCAKICAgICAgICAgICAgbGluZXdpZHRoID0gMS41KSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDMpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh5ID0gIlNpemUgVmFyaWFuY2UiLAogICAgICAgeCA9ICJTZWFzb24iKSArCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCAKICAgICAgICBsZWdlbmQudGl0bGUuYWxpZ24gPSAwLjEyNSkKYGBgCgpgYGB7ciB2YXItY2hhbmdlLXRlbXAtY2hhbmdlLCBpbmNsdWRlID0gRn0KdmFyX2NoYW5nZV9kYXRhID0gdHJhaXRfcmFuZ2VzICU+JSAgCiAgdW5ncm91cCgpICU+JSAKICBtdXRhdGUobWVhbl93dCA9IG1lYW5fY3RtYXggLSBjb2xsZWN0aW9uX3RlbXApICU+JSAKICBncm91cF9ieShzaXRlKSAlPiUgCiAgYXJyYW5nZShzaXRlLCBkb3kpICU+JSAgCiAgbXV0YXRlKHRlbXBfY2hhbmdlID0gY29sbGVjdGlvbl90ZW1wIC0gbGFnKGNvbGxlY3Rpb25fdGVtcCksCiAgICAgICAgIGN0bWF4X2NoYW5nZSA9IG1lYW5fY3RtYXggLSBsYWcobWVhbl9jdG1heCksCiAgICAgICAgIHd0X2NoYW5nZSA9IG1lYW5fd3QgLSBsYWcobWVhbl93dCksCiAgICAgICAgIHZhcl9jaGFuZ2UgPSBjdG1heF92YXIgLSBsYWcoY3RtYXhfdmFyKSkgJT4lICAKICBzZWxlY3Qoc2l0ZSwgc2Vhc29uLCBkb3ksIGxhdCwgdGVtcF9jaGFuZ2UsIHZhcl9jaGFuZ2UsIGN0bWF4X2NoYW5nZSwgd3RfY2hhbmdlKQoKZ2dwbG90KHZhcl9jaGFuZ2VfZGF0YSwgYWVzKHggPSB0ZW1wX2NoYW5nZSwgeSA9IHZhcl9jaGFuZ2UpKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCkgKyAKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIikgKwogIGdlb21fcG9pbnQoYWVzKGNvbG91ciA9IHNpdGUpLAogICAgICAgICAgICAgc2l6ZSA9IDMpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh4ID0gIlRlbXBlcmF0dXJlIENoYW5nZSAowrBDKSIsCiAgICAgICB5ID0gIkNoYW5nZSBpbiBDVG1heCBWYXJpYW5jZSIpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwgCiAgICAgICAgbGVnZW5kLnRpdGxlLmFsaWduID0gMC4xMjUpCgp2YXJfY2hhbmdlX2RhdGEgJT4lIAogIG11dGF0ZShzYW1wbGVfYXJyID0gY3RtYXhfY2hhbmdlL3RlbXBfY2hhbmdlKSAlPiUgCiAgc2VsZWN0KHNpdGUsIHNlYXNvbiwgdGVtcF9jaGFuZ2UsIHNhbXBsZV9hcnIpICU+JSAKICBkcm9wX25hKCkgJT4lIAogIGdncGxvdChhZXMoeCA9IHRlbXBfY2hhbmdlLCB5ID0gc2FtcGxlX2FyciwgY29sb3VyID0gc2l0ZSkpICsgCiAgZ2VvbV9wb2ludCgpICsgCiAgICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgCgp2YXJfY2hhbmdlX2RhdGEgJT4lIAogIG11dGF0ZShzYW1wbGVfYXJyID0gY3RtYXhfY2hhbmdlL3RlbXBfY2hhbmdlKSAlPiUgCiAgc2VsZWN0KHNpdGUsIHNlYXNvbiwgdGVtcF9jaGFuZ2UsIHNhbXBsZV9hcnIpICU+JSAKICBkcm9wX25hKCkgJT4lIAogIGdncGxvdChhZXMoeCA9IHNhbXBsZV9hcnIpKSArIAogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMC4xKQoKYGBgCgpgYGB7cn0KCmtuaXRyOjprbml0X2V4aXQoKQoKYGBgCgoKIyMgQ29tcGFyaW5nIHJhdGVzIG9mIGNoYW5nZQpCb3RoIENUbWF4IGFuZCBib2R5IHNpemUgdmFyaWVkIGJldHdlZW4gc2l0ZXMgYW5kIGFjcm9zcyBzZWFzb25zLiBJdCBjYW4gYmUgZGlmZmljdWx0IHRvIGRpcmVjdGx5IGNvbXBhcmUgdGhlc2UgdHdvIHRyYWl0cy4gV2UgdGFrZSB0d28gYXBwcm9hY2hlcyB0byBlYXNlIHRoaXMgY29tcGFyaXNvbi4gCgpTaG93biBiZWxvdyBpcyBhIGNvbXBhcmlzb24gb2YgdGhlIHNsb3BlcyBmcm9tIHRoZSB0cmFpdCByZWdyZXNzaW9ucyBhZ2FpbnN0IGNvbGxlY3Rpb24gdGVtcGVyYXR1cmUgZm9yIGVhY2ggcG9wdWxhdGlvbiwgc3RhbmRhcmRpemVkIGJ5IHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gb2YgdGhlIHRyYWl0IGZvciBlYWNoIHBvcHVsYXRpb24gKGFjcm9zcyBhbGwgY29sbGVjdGlvbnMpLiBUaGlzIHN0YW5kYXJkaXplcyB0cmFpdCBjaGFuZ2UgaW4gdW5pdHMgb2Ygc3RhbmRhcmQgZGV2aWF0aW9ucyBwZXIgZGVncmVlIGNoYW5nZSBpbiBjb2xsZWN0aW9uIHRlbXBlcmF0dXJlIGZvciBib3RoIENUbWF4IGFuZCBib2R5IHNpemUuCgpgYGB7ciBhZGotc2xvcGUtY29tcCwgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9Nn0KYWRqX3Nsb3BlcyA9IGZ1bGxfZGF0YSAlPiUgCiAgZ3JvdXBfYnkoc2l0ZSwgbGF0KSAlPiUgCiAgYXJyYW5nZShkb3kpICU+JSAgCiAgZmlsdGVyKHNpdGUgIT0gIktleSBMYXJnbyIpICU+JQogIHN1bW1hcml6ZSgiY3RtYXhfc2xvcGUiID0gY29lZihsbShjdG1heCB+IGNvbGxlY3Rpb25fdGVtcCkpWyJjb2xsZWN0aW9uX3RlbXAiXSwgCiAgICAgICAgICAgICJtZWFuX2N0bWF4IiA9IG1lYW4oY3RtYXgpLAogICAgICAgICAgICAiY3RtYXhfc2QiID0gc2QoY3RtYXgpLAogICAgICAgICAgICAic2l6ZV9zbG9wZSIgPSBjb2VmKGxtKHNpemUgfiBjb2xsZWN0aW9uX3RlbXApKVsiY29sbGVjdGlvbl90ZW1wIl0sIAogICAgICAgICAgICAibWVhbl9zaXplIiA9IG1lYW4oc2l6ZSksCiAgICAgICAgICAgICJzaXplX3NkIiA9IHNkKHNpemUpLCAKICAgICAgICAgICAgInRlbXBfcmFuZ2UiID0gbWF4KGNvbGxlY3Rpb25fdGVtcCkgLSBtaW4oY29sbGVjdGlvbl90ZW1wKSkgJT4lICAKICBkcm9wX25hKCkgJT4lIAogIG11dGF0ZShhZGpfY3RtYXhfc2xvcGUgPSBjdG1heF9zbG9wZSAvIGN0bWF4X3NkLAogICAgICAgICBhZGpfc2l6ZV9zbG9wZSA9IHNpemVfc2xvcGUgLyBzaXplX3NkKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjb250YWlucygiX3Nsb3BlIiksIAogICAgICAgICAgICAgICBuYW1lc190byA9ICJzbG9wZV90eXBlIiwKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInNsb3BlIikKCiMgZ2dwbG90KGFkal9zbG9wZXMsIGFlcyh4ID0gbGF0LCB5ID0gdGVtcF9yYW5nZSkpICsgCiMgICBnZW9tX3BvaW50KCkgKyAKIyAgIHRoZW1lX21hdHQoKQoKZ2dwbG90KGZpbHRlcihhZGpfc2xvcGVzLCBzdHJfZGV0ZWN0KHNsb3BlX3R5cGUsICJhZGpfIikpLCBhZXMoeCA9IHNsb3BlX3R5cGUsIHkgPSBhYnMoc2xvcGUpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXAgPSBzaXRlLCBjb2xvdXIgPSBzaXRlKSkgKyAKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwKSArIAogIGdlb21fbGluZShsaW5ld2lkdGggPSAxKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2l0ZV9jb2xzKSArIAogIGxhYnMoeCA9ICIiLCAKICAgICAgIHkgPSAiU2xvcGUgKGFic29sdXRlIHZhbHVlKSIpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDMwMCwgaGp1c3QgPSAwLCB2anVzdCA9IDAuNSkpCmBgYAoKSGFsZGFuZXMgYXJlIGEgc2ltaWxhciB1bml0LCByZXByZXNlbnRpbmcgY2hhbmdlIGluIHVuaXRzIG9mIHN0YW5kYXJkIGRldmlhdGlvbnMgcGVyIGdlbmVyYXRpb24uIFRoaXMgY2FuIGJlIGEgdXNlZnVsIG1ldHJpYyBmb3IgY29tcGFyaW5nIGFjcm9zcyB0cmFpdHMsIGVzcGVjaWFsbHkgYXMgdGhlIG51bWJlciBvZiBnZW5lcmF0aW9ucyBjb3ZlcmVkIGJ5IG91ciBzYW1wbGluZyBwZXJpb2QgbGlrZWx5IHZhcmllcyBhY3Jvc3MgcG9wdWxhdGlvbnMuIFRoZSBjYWxjdWxhdGlvbiBvZiBoYWxkYW5lcyBpcyB0YWtlbiBmcm9tIEhlbmRyeSBhbmQgS2lubmlzb24gKDE5OTkpLCB3aGljaCBpbiB0dXJuIGlzIGJhc2VkIG9uIHdvcmsgZnJvbSBHaW5nZXJpY2ggKDE5OTMpLiBXZSBlc3RpbWF0ZWQgdGhlIG51bWJlciBvZiBnZW5lcmF0aW9ucyBwYXNzZWQgYmV0d2VlbiBjb2xsZWN0aW9ucyB1c2luZyB0aGUgZW1waXJpY2FsIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRlbXBlcmF0dXJlIGFuZCBkZXZlbG9wbWVudCB0aW1lIGZvciAqQWNhcnRpYSB0b25zYSogZnJvbSBMZWFuZHJvIGV0IGFsLiAoMjAwNikuIEZvciBpbml0aWFsIGVzdGltYXRlcywgd2UgdXNlZCBhIHRlbXBlcmF0dXJlIGhhbGZ3YXkgYmV0d2VlbiB3aGF0IHdhcyBvYnNlcnZlZCBkdXJpbmcgY29sbGVjdGlvbiwgYWx0aG91Z2ggdGhpcyBlc3RpbWF0ZSBjYW4gYmUgaW1wcm92ZWQgYnkgdXNpbmcgbm9uLWxpbmVhciBhdmVyYWdpbmcgdG8gYWNjb3VudCBmb3IgSmVuemVuJ3MgSW5lcXVhbGl0eSBhbmQgdGhlIGVmZmVjdCBvZiB0ZW1wZXJhdHVyZSB2YXJpYXRpb24gb24gcmF0ZSBmdW5jdGlvbnMuIENoYW5nZXMgd2VyZSBleGFtaW5lZCBmb3IgZWFjaCBwYWlyIG9mIGNvbGxlY3Rpb25zIChlYXJseSB0byBwZWFrLCBhbmQgcGVhayB0byBsYXRlKS4gICAgCgpTaG93biBiZWxvdyBpcyBhIGNvbXBhcmlzb24gb2YgdGhlIGVzdGltYXRlZCBoYWxkYW5lIHZhbHVlcyBmb3IgQ1RtYXggYW5kIGJvZHkgc2l6ZSwgc2VwYXJhdGVkIGJ5IHNlYXNvbi4gS2VlcCBpbiBtaW5kIHRoYXQgd2hpbGUgdGhpcyBtZXRyaWMgYWNjb3VudHMgZm9yIGRpZmZlcmVuY2VzIGluIHRoZSBudW1iZXIgb2YgZ2VuZXJhdGlvbnMgYmV0d2VlbiBjb2xsZWN0aW9ucywgaXQgZG9lcyBub3QgZGlyZWN0bHkgYWNjb3VudCBmb3IgZGlmZmVyZW5jZXMgaW4gdGVtcGVyYXR1cmUsIGxlYWRpbmcgdG8gaW5mbGF0ZWQgdmFsdWVzIGluIHRoZSAicGVhayB0byBsYXRlIiBjb21wYXJpc29ucywgd2hpY2ggdHlwaWNhbGx5IGNvdmVyZWQgYSBsYXJnZXIgcmFuZ2Ugb2YgdGVtcGVyYXR1cmVzLiAKCmBgYHtyIGhhbGRhbmUtY29tcC1wbG90LCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xMn0KZWFybHlfcGVhayA9IGZ1bGxfZGF0YSAlPiUgCiAgZmlsdGVyKHNlYXNvbiAlaW4lIGMoImVhcmx5IiwgInBlYWsiKSkgJT4lIAogIG11dGF0ZShzZWFzb24gPSBpZl9lbHNlKHNlYXNvbiA9PSAiZWFybHkiLCAib25lIiwgInR3byIpKSAlPiUgCiAgZ3JvdXBfYnkoc2l0ZSkgJT4lIAogIG11dGF0ZShjdG1heF9zZF9wID0gc2QoY3RtYXgpLAogICAgICAgICBzaXplX3NkX3AgPSBzZChzaXplKSwgCiAgICAgICAgIHRlbXBfY2hhbmdlID0gbWF4KGNvbGxlY3Rpb25fdGVtcCkgLSBtaW4oY29sbGVjdGlvbl90ZW1wKSwKICAgICAgICAgYXZnX3RlbXAgPSAobWF4KGNvbGxlY3Rpb25fdGVtcCkgKyBtaW4oY29sbGVjdGlvbl90ZW1wKSkgLyAyLAogICAgICAgICBkYXlzX3Bhc3NlZCA9IG1heChkb3kpIC0gbWluKGRveSkpICU+JSAKICBzZWxlY3Qoc2l0ZSwgbGF0LCBzZWFzb24sIAogICAgICAgICBjdG1heF9zZF9wLCBzaXplX3NkX3AsIAogICAgICAgICB0ZW1wX2NoYW5nZSwgYXZnX3RlbXAsIGRheXNfcGFzc2VkLCAKICAgICAgICAgY3RtYXgsIHNpemUpICU+JQogIGdyb3VwX2J5KHNpdGUsIGxhdCwgc2Vhc29uLCAKICAgICAgICAgICBjdG1heF9zZF9wLCBzaXplX3NkX3AsIAogICAgICAgICAgIHRlbXBfY2hhbmdlLCBhdmdfdGVtcCwgZGF5c19wYXNzZWQpICU+JSAKICBzdW1tYXJpemUoY3RtYXggPSBtZWFuKGN0bWF4KSwKICAgICAgICAgICAgc2l6ZSA9IG1lYW4oc2l6ZSkpICU+JSAKICBwaXZvdF93aWRlcihpZF9jb2xzID0gYyhzaXRlLCBsYXQsIGN0bWF4X3NkX3AsIHNpemVfc2RfcCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcF9jaGFuZ2UsIGF2Z190ZW1wLCBkYXlzX3Bhc3NlZCksIAogICAgICAgICAgICAgIG5hbWVzX2Zyb20gPSBzZWFzb24sIAogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gYyhjdG1heCwgc2l6ZSkpICU+JSAKICBtdXRhdGUoc2Vhc29uID0gImVhcmx5X3RvX3BlYWsiKSAlPiUgIAogIGRyb3BfbmEoKQoKcGVha19sYXRlID0gZnVsbF9kYXRhICU+JSAKICBmaWx0ZXIoc2Vhc29uICVpbiUgYygicGVhayIsICJsYXRlIikpICU+JSAKICBtdXRhdGUoc2Vhc29uID0gaWZfZWxzZShzZWFzb24gPT0gInBlYWsiLCAib25lIiwgInR3byIpKSAlPiUgCiAgZ3JvdXBfYnkoc2l0ZSkgJT4lIAogIG11dGF0ZShjdG1heF9zZF9wID0gc2QoY3RtYXgpLAogICAgICAgICBzaXplX3NkX3AgPSBzZChzaXplKSwgCiAgICAgICAgIHRlbXBfY2hhbmdlID0gbGFzdChjb2xsZWN0aW9uX3RlbXApIC0gZmlyc3QoY29sbGVjdGlvbl90ZW1wKSwKICAgICAgICAgYXZnX3RlbXAgPSAobWF4KGNvbGxlY3Rpb25fdGVtcCkgKyBtaW4oY29sbGVjdGlvbl90ZW1wKSkgLyAyLAogICAgICAgICBkYXlzX3Bhc3NlZCA9IG1heChkb3kpIC0gbWluKGRveSkpICU+JSAKICBzZWxlY3Qoc2l0ZSwgbGF0LCBzZWFzb24sIGN0bWF4X3NkX3AsIHNpemVfc2RfcCwgCiAgICAgICAgIHRlbXBfY2hhbmdlLCBhdmdfdGVtcCwgZGF5c19wYXNzZWQsIAogICAgICAgICBjdG1heCwgc2l6ZSkgJT4lCiAgZ3JvdXBfYnkoc2l0ZSwgbGF0LCBzZWFzb24sIGN0bWF4X3NkX3AsIHNpemVfc2RfcCwgCiAgICAgICAgICAgdGVtcF9jaGFuZ2UsIGF2Z190ZW1wLCBkYXlzX3Bhc3NlZCkgJT4lIAogIHN1bW1hcml6ZShjdG1heCA9IG1lYW4oY3RtYXgpLAogICAgICAgICAgICBzaXplID0gbWVhbihzaXplKSkgJT4lIAogIHBpdm90X3dpZGVyKGlkX2NvbHMgPSBjKHNpdGUsIGxhdCwgY3RtYXhfc2RfcCwgc2l6ZV9zZF9wLCAKICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wX2NoYW5nZSwgYXZnX3RlbXAsIGRheXNfcGFzc2VkKSwgCiAgICAgICAgICAgICAgbmFtZXNfZnJvbSA9IHNlYXNvbiwgCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSBjKGN0bWF4LCBzaXplKSkgJT4lIAogIG11dGF0ZShzZWFzb24gPSAicGVha190b19sYXRlIikgJT4lICAKICBkcm9wX25hKCkKCmNhbGNfaGFsZHMgPSBmdW5jdGlvbih4MSwgeDIsIHNkX3AsIGcpewogICgoeDIgLyBzZF9wKSAtICh4MSAvIHNkX3ApKSAvIGcKfQoKaGFsZGFuZXMgPSBiaW5kX3Jvd3MoZWFybHlfcGVhaywgcGVha19sYXRlKSAlPiUgCiAgbXV0YXRlKCJnZW5fdGltZSIgPSA1NDkwKihhdmdfdGVtcCArIDEpXi0yLjA1LCAKICAgICAgICAgImdlbnMiID0gZmxvb3IoZGF5c19wYXNzZWQgLyBnZW5fdGltZSksCiAgICAgICAgICJjdG1heF9oYWxkYW5lcyIgPSBjYWxjX2hhbGRzKHgyID0gY3RtYXhfdHdvLCB4MSA9IGN0bWF4X29uZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNkX3AgPSBjdG1heF9zZF9wLCBnID0gZ2VucyksCiAgICAgICAgICJzaXplX2hhbGRhbmVzIiA9IGNhbGNfaGFsZHMoeDIgPSBzaXplX3R3bywgeDEgPSBzaXplX29uZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2RfcCA9IHNpemVfc2RfcCwgZyA9IGdlbnMpKQoKIyBoYWxkYW5lcyAlPiUgCiMgICB1bmdyb3VwKCkgJT4lIAojICAgc2VsZWN0KHNpdGUsIHRlbXBfY2hhbmdlLCBzZWFzb24sIGN0bWF4X2hhbGRhbmVzLCBzaXplX2hhbGRhbmVzKSAlPiUgCiMgICBwaXZvdF9sb25nZXIoY29scyA9IGMoY3RtYXhfaGFsZGFuZXMsIHNpemVfaGFsZGFuZXMpLAojICAgICAgICAgICAgICAgIG5hbWVzX3RvID0gYygidHlwZSIsIE5BKSwgCiMgICAgICAgICAgICAgICAgbmFtZXNfc2VwID0gIl8iLAojICAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJoYWxkYW5lcyIpICU+JSAKIyAgIGdncGxvdChhZXMoeCA9IHR5cGUsIHkgPSBoYWxkYW5lcywgZ3JvdXAgPSBzaXRlLCBjb2xvdXIgPSBzaXRlKSkgKyAKIyAgIGZhY2V0X3dyYXAoc2Vhc29ufi4pICsgCiMgICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwKSArIAojICAgZ2VvbV9saW5lKGFlcyhsaW5ld2lkdGggPSBkZXNjKHRlbXBfY2hhbmdlKSkpICsgCiMgICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgKyAKIyAgIGxhYnMoeCA9ICJUcmFpdCIsIAojICAgICAgICB5ID0gIkhhbGRhbmVzIiwgCiMgICAgICAgIGxpbmV3aWR0aCA9ICJUZW1wLiBDaGFuZ2UiKSArIAojICAgdGhlbWVfbWF0dF9mYWNldHMoKQoKY3RtYXhfaGFsZHNfcGxvdCA9IGhhbGRhbmVzICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIHNlbGVjdChzaXRlLCB0ZW1wX2NoYW5nZSwgc2Vhc29uLCBjdG1heF9oYWxkYW5lcywgc2l6ZV9oYWxkYW5lcykgJT4lICAgCiAgZ2dwbG90KGFlcyh4ID0gc2Vhc29uLCB5ID0gY3RtYXhfaGFsZGFuZXMsIGNvbG91ciA9IHNpdGUsIGdyb3VwID0gc2l0ZSkpICsgCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgY29sb3VyID0gImdyZXk3MCIpICsgCiAgZ2VvbV9saW5lKGxpbmV3aWR0aCA9IDIpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh4ID0gIlNlYXNvbiIsCiAgICAgICB5ID0gIkhhbGRhbmVzIikgKyAKICBnZ3RpdGxlKCJDVG1heCIpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKCnNpemVfaGFsZHNfcGxvdCA9IGhhbGRhbmVzICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIHNlbGVjdChzaXRlLCB0ZW1wX2NoYW5nZSwgc2Vhc29uLCBjdG1heF9oYWxkYW5lcywgc2l6ZV9oYWxkYW5lcykgJT4lICAgCiAgZ2dwbG90KGFlcyh4ID0gc2Vhc29uLCB5ID0gc2l6ZV9oYWxkYW5lcywgY29sb3VyID0gc2l0ZSwgZ3JvdXAgPSBzaXRlKSkgKyAKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBjb2xvdXIgPSAiZ3JleTcwIikgKyAKICBnZW9tX2xpbmUobGluZXdpZHRoID0gMikgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgKyAKICBsYWJzKHggPSAiU2Vhc29uIiwKICAgICAgIHkgPSAiSGFsZGFuZXMiKSArIAogIGdndGl0bGUoIlNpemUiKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgpnZ2FycmFuZ2UoY3RtYXhfaGFsZHNfcGxvdCwgc2l6ZV9oYWxkc19wbG90LCBjb21tb24ubGVnZW5kID0gVCwgbGVnZW5kID0gImJvdHRvbSIpCmBgYAoKYGBge3IgaGFsZGFuZS1yZXNpZHMtY29tcC1wbG90LCBmaWcuaGVpZ2h0PTMuNSwgZmlnLndpZHRoPTksIGluY2x1ZGUgPSBGfQplYXJseV9wZWFrX3Jlc2lkcyA9IHVuaXZlcnNhbF9yZXNpZHMgJT4lIAogIGZpbHRlcihzZWFzb24gJWluJSBjKCJlYXJseSIsICJwZWFrIikpICU+JSAKICBtdXRhdGUoc2Vhc29uID0gaWZfZWxzZShzZWFzb24gPT0gImVhcmx5IiwgIm9uZSIsICJ0d28iKSkgJT4lIAogIGdyb3VwX2J5KHNpdGUpICU+JSAKICBtdXRhdGUoY3RtYXhfc2RfcCA9IHNkKGN0bWF4X3Jlc2lkcyksCiAgICAgICAgIHNpemVfc2RfcCA9IHNkKHNpemVfcmVzaWRzKSwgCiAgICAgICAgIHRlbXBfY2hhbmdlID0gbWF4KGNvbGxlY3Rpb25fdGVtcCkgLSBtaW4oY29sbGVjdGlvbl90ZW1wKSwKICAgICAgICAgYXZnX3RlbXAgPSAobWF4KGNvbGxlY3Rpb25fdGVtcCkgKyBtaW4oY29sbGVjdGlvbl90ZW1wKSkgLyAyLAogICAgICAgICBkYXlzX3Bhc3NlZCA9IG1heChkb3kpIC0gbWluKGRveSkpICU+JSAKICBzZWxlY3Qoc2l0ZSwgbGF0LCBzZWFzb24sIAogICAgICAgICBjdG1heF9zZF9wLCBzaXplX3NkX3AsIAogICAgICAgICB0ZW1wX2NoYW5nZSwgYXZnX3RlbXAsIGRheXNfcGFzc2VkLCAKICAgICAgICAgY3RtYXhfcmVzaWRzLCBzaXplX3Jlc2lkcykgJT4lCiAgZ3JvdXBfYnkoc2l0ZSwgbGF0LCBzZWFzb24sIAogICAgICAgICAgIGN0bWF4X3NkX3AsIHNpemVfc2RfcCwgCiAgICAgICAgICAgdGVtcF9jaGFuZ2UsIGF2Z190ZW1wLCBkYXlzX3Bhc3NlZCkgJT4lIAogIHN1bW1hcml6ZShjdG1heCA9IG1lYW4oY3RtYXhfcmVzaWRzKSwKICAgICAgICAgICAgc2l6ZSA9IG1lYW4oc2l6ZV9yZXNpZHMpKSAlPiUgCiAgcGl2b3Rfd2lkZXIoaWRfY29scyA9IGMoc2l0ZSwgbGF0LCBjdG1heF9zZF9wLCBzaXplX3NkX3AsIAogICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBfY2hhbmdlLCBhdmdfdGVtcCwgZGF5c19wYXNzZWQpLCAKICAgICAgICAgICAgICBuYW1lc19mcm9tID0gc2Vhc29uLCAKICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IGMoY3RtYXgsIHNpemUpKSAlPiUgCiAgbXV0YXRlKHNlYXNvbiA9ICJlYXJseV90b19wZWFrIikgJT4lICAKICBkcm9wX25hKCkKCnBlYWtfbGF0ZV9yZXNpZHMgPSB1bml2ZXJzYWxfcmVzaWRzICU+JSAKICBmaWx0ZXIoc2Vhc29uICVpbiUgYygicGVhayIsICJsYXRlIikpICU+JSAKICBtdXRhdGUoc2Vhc29uID0gaWZfZWxzZShzZWFzb24gPT0gInBlYWsiLCAib25lIiwgInR3byIpKSAlPiUgCiAgZ3JvdXBfYnkoc2l0ZSkgJT4lIAogIG11dGF0ZShjdG1heF9zZF9wID0gc2QoY3RtYXhfcmVzaWRzKSwKICAgICAgICAgc2l6ZV9zZF9wID0gc2Qoc2l6ZV9yZXNpZHMpLCAKICAgICAgICAgdGVtcF9jaGFuZ2UgPSBsYXN0KGNvbGxlY3Rpb25fdGVtcCkgLSBmaXJzdChjb2xsZWN0aW9uX3RlbXApLAogICAgICAgICBhdmdfdGVtcCA9IChtYXgoY29sbGVjdGlvbl90ZW1wKSArIG1pbihjb2xsZWN0aW9uX3RlbXApKSAvIDIsCiAgICAgICAgIGRheXNfcGFzc2VkID0gbWF4KGRveSkgLSBtaW4oZG95KSkgJT4lIAogIHNlbGVjdChzaXRlLCBsYXQsIHNlYXNvbiwgY3RtYXhfc2RfcCwgc2l6ZV9zZF9wLCAKICAgICAgICAgdGVtcF9jaGFuZ2UsIGF2Z190ZW1wLCBkYXlzX3Bhc3NlZCwgCiAgICAgICAgIGN0bWF4X3Jlc2lkcywgc2l6ZV9yZXNpZHMpICU+JQogIGdyb3VwX2J5KHNpdGUsIGxhdCwgc2Vhc29uLCBjdG1heF9zZF9wLCBzaXplX3NkX3AsIAogICAgICAgICAgIHRlbXBfY2hhbmdlLCBhdmdfdGVtcCwgZGF5c19wYXNzZWQpICU+JSAKICBzdW1tYXJpemUoY3RtYXggPSBtZWFuKGN0bWF4X3Jlc2lkcyksCiAgICAgICAgICAgIHNpemUgPSBtZWFuKHNpemVfcmVzaWRzKSkgJT4lIAogIHBpdm90X3dpZGVyKGlkX2NvbHMgPSBjKHNpdGUsIGxhdCwgY3RtYXhfc2RfcCwgc2l6ZV9zZF9wLCAKICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wX2NoYW5nZSwgYXZnX3RlbXAsIGRheXNfcGFzc2VkKSwgCiAgICAgICAgICAgICAgbmFtZXNfZnJvbSA9IHNlYXNvbiwgCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSBjKGN0bWF4LCBzaXplKSkgJT4lIAogIG11dGF0ZShzZWFzb24gPSAicGVha190b19sYXRlIikgJT4lICAKICBkcm9wX25hKCkKCmNhbGNfaGFsZHMgPSBmdW5jdGlvbih4MSwgeDIsIHNkX3AsIGcpewogICgoeDIgLyBzZF9wKSAtICh4MSAvIHNkX3ApKSAvIGcKfQoKaGFsZGFuZXNfcmVzaWRzID0gYmluZF9yb3dzKGVhcmx5X3BlYWtfcmVzaWRzLCBwZWFrX2xhdGVfcmVzaWRzKSAlPiUgCiAgbXV0YXRlKCJnZW5fdGltZSIgPSA1NDkwKihhdmdfdGVtcCArIDEpXi0yLjA1LCAKICAgICAgICAgImdlbnMiID0gZmxvb3IoZGF5c19wYXNzZWQgLyBnZW5fdGltZSksCiAgICAgICAgICJjdG1heF9oYWxkYW5lcyIgPSBjYWxjX2hhbGRzKHgyID0gY3RtYXhfdHdvLCB4MSA9IGN0bWF4X29uZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNkX3AgPSBjdG1heF9zZF9wLCBnID0gZ2VucyksCiAgICAgICAgICJzaXplX2hhbGRhbmVzIiA9IGNhbGNfaGFsZHMoeDIgPSBzaXplX3R3bywgeDEgPSBzaXplX29uZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2RfcCA9IHNpemVfc2RfcCwgZyA9IGdlbnMpKQoKIyBoYWxkYW5lc19yZXNpZHMgJT4lIAojICAgdW5ncm91cCgpICU+JSAKIyAgIHNlbGVjdChzaXRlLCB0ZW1wX2NoYW5nZSwgc2Vhc29uLCBjdG1heF9oYWxkYW5lcywgc2l6ZV9oYWxkYW5lcykgJT4lIAojICAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKGN0bWF4X2hhbGRhbmVzLCBzaXplX2hhbGRhbmVzKSwKIyAgICAgICAgICAgICAgICBuYW1lc190byA9IGMoInR5cGUiLCBOQSksIAojICAgICAgICAgICAgICAgIG5hbWVzX3NlcCA9ICJfIiwKIyAgICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAiaGFsZGFuZXMiKSAlPiUgCiMgICBnZ3Bsb3QoYWVzKHggPSB0eXBlLCB5ID0gaGFsZGFuZXMsIGdyb3VwID0gc2l0ZSwgY29sb3VyID0gc2l0ZSkpICsgCiMgICBmYWNldF93cmFwKHNlYXNvbn4uKSArIAojICAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCkgKyAKIyAgIGdlb21fbGluZShhZXMobGluZXdpZHRoID0gZGVzYyh0ZW1wX2NoYW5nZSkpKSArIAojICAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiMgICBsYWJzKHggPSAiVHJhaXQiLCAKIyAgICAgICAgeSA9ICJIYWxkYW5lcyIsIAojICAgICAgICBsaW5ld2lkdGggPSAiVGVtcC4gQ2hhbmdlIikgKyAKIyAgIHRoZW1lX21hdHRfZmFjZXRzKCkKCgpyZXNpZHNfY3RtYXhfaGFsZHNfcGxvdCA9IGhhbGRhbmVzX3Jlc2lkcyAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBzZWxlY3Qoc2l0ZSwgdGVtcF9jaGFuZ2UsIHNlYXNvbiwgY3RtYXhfaGFsZGFuZXMsIHNpemVfaGFsZGFuZXMpICU+JSAgIAogIGdncGxvdChhZXMoeCA9IHNlYXNvbiwgeSA9IGN0bWF4X2hhbGRhbmVzLCBjb2xvdXIgPSBzaXRlLCBncm91cCA9IHNpdGUpKSArIAogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGNvbG91ciA9ICJncmV5NzAiKSArIAogIGdlb21fbGluZShsaW5ld2lkdGggPSAyKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2l0ZV9jb2xzKSArIAogIGxhYnMoeCA9ICJTZWFzb24iLAogICAgICAgeSA9ICJIYWxkYW5lcyIpICsgCiAgZ2d0aXRsZSgiQ1RtYXgiKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgpyZXNpZHNfc2l6ZV9oYWxkc19wbG90ID0gaGFsZGFuZXNfcmVzaWRzICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIHNlbGVjdChzaXRlLCB0ZW1wX2NoYW5nZSwgc2Vhc29uLCBjdG1heF9oYWxkYW5lcywgc2l6ZV9oYWxkYW5lcykgJT4lICAgCiAgZ2dwbG90KGFlcyh4ID0gc2Vhc29uLCB5ID0gc2l6ZV9oYWxkYW5lcywgY29sb3VyID0gc2l0ZSwgZ3JvdXAgPSBzaXRlKSkgKyAKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBjb2xvdXIgPSAiZ3JleTcwIikgKyAKICBnZW9tX2xpbmUobGluZXdpZHRoID0gMikgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgKyAKICBsYWJzKHggPSAiU2Vhc29uIiwKICAgICAgIHkgPSAiSGFsZGFuZXMiKSArIAogIGdndGl0bGUoIlNpemUiKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgpnZ2FycmFuZ2UocmVzaWRzX2N0bWF4X2hhbGRzX3Bsb3QsIHJlc2lkc19zaXplX2hhbGRzX3Bsb3QsIGNvbW1vbi5sZWdlbmQgPSBULCBsZWdlbmQgPSAiYm90dG9tIikKYGBgCgpgYGB7ciBoYWxkYW5lcy1sYXQtcGxvdCwgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTgsIGluY2x1ZGUgPSBGfQojIFNob3duIGJlbG93IGFyZSB0aGUgaGFsZGFuZSB2YWx1ZXMgcGxvdHRlZCBhZ2FpbnN0IGxhdGl0dWRlLiBOb3RlIHRoYXQgZXZlbiB0aG91Z2ggbGFyZ2UgY2hhbmdlcyBpbiB0ZW1wZXJhdHVyZSBvY2N1cnJlZCBiZXR3ZWVuIHBlYWsgYW5kIGxhdGUgc2FtcGxlcyBpbiB0aGUgQ2hlc2FwZWFrZSwgdGhlIGNoYW5nZSBpbiBoYWxkYW5lcyBpcyByZWxhdGl2ZWx5IHNtYWxsLCB3aGlsZSBpbiB0aGUgTm9ydGhlcm4gcG9wdWxhdGlvbnMsIGNoYW5nZXMgYXJlIGxhcmdlciwgdGhvdWdoIG1vcmUgdmFyaWFibGUuIAoKY3RtYXhfaGFsZGFuZXMgPSBnZ3Bsb3QoaGFsZGFuZXMsIGFlcyh4ID0gbGF0LCB5ID0gY3RtYXhfaGFsZGFuZXMsIGNvbG91ciA9IHNpdGUsIHNoYXBlID0gc2Vhc29uKSkgKyAKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwKSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDMpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh4ID0gIkxhdGl0dWRlIiwKICAgICAgIHkgPSAiQ2hhbmdlIGluIENUbWF4IChoYWxkYW5lcykiKSArIAogIHRoZW1lX21hdHRfZmFjZXRzKCkKCnNpemVfaGFsZGFuZXMgPSBnZ3Bsb3QoaGFsZGFuZXMsIGFlcyh4ID0gbGF0LCB5ID0gc2l6ZV9oYWxkYW5lcywgY29sb3VyID0gc2l0ZSwgc2hhcGUgPSBzZWFzb24pKSArIAogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDApICsgCiAgZ2VvbV9wb2ludChzaXplID0gMykgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgKyAKICBsYWJzKHggPSAiTGF0aXR1ZGUiLAogICAgICAgeSA9ICJDaGFuZ2UgaW4gU2l6ZSAoaGFsZGFuZXMpIikgKyAKICB0aGVtZV9tYXR0X2ZhY2V0cygpCgpnZ2FycmFuZ2UoY3RtYXhfaGFsZGFuZXMsIHNpemVfaGFsZGFuZXMsIGNvbW1vbi5sZWdlbmQgPSBULCBsZWdlbmQgPSAicmlnaHQiLCBucm93ID0gMikKYGBgCgojIyBXaHkgZG9lcyBpbnRyYXNwZWNpZmljIGRhdGEgbWF0dGVyPyAKClRoZXJtYWwgbGltaXRzIHZhcnkgc3Vic3RhbnRpYWxseSBhY3Jvc3MgYm90aCBzcGF0aWFsIGFuZCB0ZW1wb3JhbCBzY2FsZXMgaW4gdGhpcyBzcGVjaWVzLCBoaWdobGlnaHRpbmcgdGhlIGltcG9ydGFuY2Ugb2YgY29uc2lkZXJpbmcgYm90aCBpbnRyYXNwZWNpZmljIGFuZCB0ZW1wb3JhbCB2YXJpYXRpb24gaW4gdGhlcm1hbCBsaW1pdHMgZm9yIHByZWRpY3Rpb25zIG9mIHZ1bG5lcmFiaWxpdHkgdG8gY2xpbWF0ZSBjaGFuZ2UuIFNpbmdsZSBwb2ludCBlc3RpbWF0ZXMgb2YgdGhlcm1hbCBsaW1pdHMgKGFzIGNvbW1vbmx5IHVzZWQgaW4gbGFyZ2VyLCBnZW5lcmFsIGFuYWx5c2VzIGFjcm9zcyB0YXhhKSBvYnNjdXJlIHRoaXMgY3J1Y2lhbCB2YXJpYXRpb24sIGFuZCBtYXkgYmlhcyBvdXIgZXN0aW1hdGVzIG9mIHNwYXRpYWwgcGF0dGVybnMgaW4gdnVsbmVyYWJpbGl0eS4gSGVyZSB3ZSBleHBsb3JlIHRocmVlIHNlcGFyYXRlIHNjZW5hcmlvcyB0byBpbGx1c3RyYXRlIGFuZCBxdWFudGlmeSB0aGUgaW1wb3J0YW5jZSBvZiB0aGlzIGludHJhc3BlY2lmaWMgdnVsbmVyYWJpbGl0eS4gCgojIyMgU2NlbmFyaW8gMSAtIEludmFyaWFudCB0aGVybWFsIGxpbWl0cwoKVGhlIGZpcnN0IHNjZW5hcmlvIGFzc3VtZXMgdGhhdCB0aGVybWFsIGxpbWl0cyBhcmUgY29uc3RhbnQgYWNyb3NzIGJvdGggc3BhdGlhbCBhbmQgdGVtcG9yYWwgYXhlcyAoaS5lLiBhIHNpbmdsZSBwb2ludCBlc3RpbWF0ZSBvZiB0aGUgdGhlcm1hbCBsaW1pdCBmb3IgdGhpcyBzcGVjaWVzKS4gSGVyZSB3ZSBzZWxlY3RlZCBhIGNlbnRyYWwgcG9wdWxhdGlvbiAodGhlIGhpZ2ggc2FsaW5pdHkgQ2hlc2FwZWFrZSBCYXkgc2l0ZSksIGFuZCB1c2VkIHRoZSBhdmVyYWdlIHRoZXJtYWwgbGltaXQgZnJvbSB0aGUgcGVhayBzZWFzb24gc2FtcGxlIGFzIG91ciAncmVwcmVzZW50YXRpdmUnIHRoZXJtYWwgbGltaXQuIFRoaXMgYXBwcm9hY2ggaXMgc2ltaWxhciB0byB0aGF0IHVzZWQgaW4gQmVubmV0IGV0IGFsLiB0byBjb21waWxlIHRoZSBHbG9iVGhlcm0gZGF0YXNldC4gVGhlc2UgdGhlcm1hbCBsaW1pdHMgYXJlIHVzZWQgdG8gcmUtZXN0aW1hdGUgd2FybWluZyB0b2xlcmFuY2UgZm9yIGVhY2ggY29sbGVjdGlvbiAobWVhbiB0aGVybWFsIGxpbWl0IC0gY29sbGVjdGlvbiB0ZW1wZXJhdHVyZSkuIFdlIHRoZW4gY29tcGFyZWQgdGhpcyBwcmVkaWN0ZWQgd2FybWluZyB0b2xlcmFuY2Ugd2l0aCB0aGUgYWN0dWFsIG9ic2VydmVkIHdhcm1pbmcgdG9sZXJhbmNlcyBmcm9tIGVhY2ggY29sbGVjdGlvbi4gQSBwb3NpdGl2ZSBkaWZmZXJlbmNlIGluZGljYXRlcyBhbiBvdmVyZXN0aW1hdGVkIHdhcm1pbmcgdG9sZXJhbmNlICh0aGUgcG9wdWxhdGlvbiBpcyBhY3R1YWxseSBjbG9zZXIgdG8gdGhlaXIgdGhlcm1hbCBsaW1pdHMgdGhhbiB3b3VsZCBiZSBwcmVkaWN0ZWQgZnJvbSB0aGUgZXN0aW1hdGVkIHZhbHVlLCBhbmQgdGhlcmVmb3JlIG1vcmUgdnVsbmVyYWJsZSkuIEEgbmVnYXRpdmUgZGlmZmVyZW5jZSBpbmRpY2F0ZXMgYW4gdW5kZXJlc3RpbWF0ZWQgd2FybWluZyB0b2xlcmFuY2UgKHRoZSBwb3B1bGF0aW9uIGlzIGZ1cnRoZXIgZnJvbSB0aGVpciB0aGVybWFsIGxpbWl0IHRoYW4gd291bGQgYmUgcHJlZGljdGVkLCBhbmQgdGhlcmVmb3JlIGxlc3MgdnVsbmVyYWJsZSkuIAoKQm90aCBvdmVyZXN0aW1hdGVzIGFuZCB1bmRlcmVzdGltYXRlcyBjYW4gYmUgcHJvYmxlbWF0aWMgZm9yIGFjY3VyYXRlIG1hbmFnZW1lbnQgYW5kIGNvbnNlcnZhdGlvbiBzdHJhdGVnaWVzLiBXZSBzdW1tYXJpemUgZWFjaCBvZiB0aGUgc2NlbmFyaW9zIHVzaW5nIDEpIHRoZSBudW1iZXIgb2YgcG9wdWxhdGlvbnMgd2l0aCBhIGRpZmZlcmVuY2UgYmV0d2VlbiBlc3RpbWF0ZXMgPjLCsEMgaW4gZWl0aGVyIGRpcmVjdGlvbiwgMikgdGhlIGF2ZXJhZ2UgbWFnbml0dWRlIG9mIGRpZmZlcmVuY2UgZm9yIHRoYXQgc3Vic2V0IG9mIHBvcHVsYXRpb25zLCBhbmQgMykgdGhlIHNsb3BlIG9mIHRoZSBkaWZmZXJlbmNlIGFnYWluc3QgbGF0aXR1ZGUuIEVmZmVjdGl2ZSBlc3RpbWF0aW9uIHN0cmF0ZWdpZXMgd2lsbCBoYXZlIGEgc21hbGwgbnVtYmVyIG9mIHBvcHVsYXRpb25zIHdpdGggdW5kZXItIG9yIG92ZXItZXN0aW1hdGVkIHdhcm1pbmcgdG9sZXJhbmNlLCBhIHNtYWxsIG1hZ25pdHVkZSBkaWZmZXJlbmNlIGJldHdlZW4gcHJlZGljdGVkIGFuZCBvYnNlcnZlZCB3YXJtaW5nIHRvbGVyYW5jZSwgYW5kIGEgc2hhbGxvdyBsYXRpdHVkaW5hbCBzbG9wZS4gCgpJbiB0aGlzIGZpcnN0IHNjZW5hcmlvIChzaW5nbGUgcG9pbnQgZXN0aW1hdGUgb2YgdGhlcm1hbCBsaW1pdHMpLCB0aGUgZWZmZWN0aXZlbmVzcyBvZiB0aGUgZXN0aW1hdGUgdmFyaWVkIGFjcm9zcyBsYXRpdHVkZSBhbmQgYWNyb3NzIHNlYXNvbnMuIER1cmluZyB0aGUgZWFybHkgc2Vhc29uLCB0aGVybWFsIGxpbWl0cyBmcm9tIHRoZSBjZW50cmFsIHNpdGUgd2VyZSBhIGRlY2VudCBwcmVkaWN0b3Igb2Ygd2FybWluZyB0b2xlcmFuY2UgYXQgdGhlIG90aGVyIHNpdGVzLCBhbmQgdGhlcmUgd2FzIG9ubHkgYSBzbGlnaHQgbGF0aXR1ZGluYWwgdHJlbmQuIFRoaXMgbGF0aXR1ZGluYWwgdHJlbmQgaW5jcmVhc2VkLCBob3dldmVyLCBkdXJpbmcgdGhlIHBlYWsgYW5kIGxhdGUgc2Vhc29uIGNvbGxlY3Rpb25zLCBkcml2ZW4gYnkgaW5jcmVhc2luZ2x5IGxhcmdlIGRpZmZlcmVuY2VzIGluIHRoZSBub3J0aGVybiBzaXRlcyAoaW5kaWNhdGluZyBpbmNyZWFzZWQgdnVsbmVyYWJpbGl0eSByZWxhdGl2ZSB0byBwcmVkaWN0aW9ucyBpbiB0aGVzZSBzaXRlcykuIER1cmluZyB0aGUgcGVhayBzZWFzb24gY29sbGVjdGlvbiwgd2FybWluZyB0b2xlcmFuY2UgaW4gdGhlIHNvdXRoZXJuIHNpdGVzIHdhcyB1bmRlcmVzdGltYXRlZCBieSBzZXZlcmFsIGRlZ3JlZXMgKHRoZXNlIHBvcHVsYXRpb25zIHdlcmUgbGVzcyB2dWxuZXJhYmxlIHRoYW4gcHJlZGljdGVkIGJ5IHRoZSBjZW50cmFsIHNpdGUgdGhlcm1hbCBsaW1pdHMpLiAKCmBgYHtyfQojIENvbXBhcmUgZXN0aW1hdGVkIHdhcm1pbmcgdG9sZXJhbmNlICJyYW5nZXMiIHdoZW46IDEpIENUbWF4IGZvciAiYXZlcmFnZSIgY29sbGVjdGlvbiBpcyB1c2VkOyAyKSBXaGVuIENUbWF4IGZvciBvbmUgY29sbGVjdGlvbiBwZXIgcG9wdWxhdGlvbiBpcyB1c2VkOyBhbmQgMykgV2hlbiBhbGwgY29sbGVjdGlvbnMgYXJlIHVzZWQuIFRoZSBpZGVhIGlzIHRvIHNob3cgdGhhdCBub3QgYWNjb3VudGluZyBmb3IgaW50cmEtc3BlY2lmaWMgYW5kIGludHJhLXBvcHVsYXRpb24gdmFyaWF0aW9uIGxlYWRzIHRvIGluY29ycmVjdCBwcmVkaWN0aW9ucyBvZiB2dWxuZXJhYmlsaXR5IHRvIHdhcm1pbmcgYmVjYXVzZSB0aGlzIHZhcmlhdGlvbiBjYW4gYmUgc3Vic3RhbnRpYWwgLSBhY3Jvc3MgcG9wdWxhdGlvbnMgd2l0aGluIGVhY2ggc2Vhc29uYWwgY29sbGVjdGlvbiwgdGhlcmUgaXMgYXQgbGVhc3QgNcKwQyB2YXJpYXRpb24gaW4gdGhlcm1hbCBsaW1pdHMsIHdoaWxlIGFjcm9zcyBjb2xsZWN0aW9ucyB3aXRoaW4gcG9wdWxhdGlvbnMsIGFjY2xpbWF0aW9uIHRvIGNoYW5nZXMgaW4gdGVtcGVyYXR1cmUgY2FuIGRyaXZlIHN1YnN0YW50aWFsIHZhcmlhdGlvbi4gCgojIyBTY2VuYXJpbyAxIC0gc2luZ2xlIHBvaW50IGVzdGltYXRlcyAKCmVzdF8xID0gZnVsbF9kYXRhICU+JSAKICBncm91cF9ieShzaXRlLCBzZWFzb24pICU+JSAKICBzdW1tYXJpc2UoIm1lYW5fY3RtYXgiID0gbWVhbihjdG1heCkpICU+JSAKICBmaWx0ZXIoc2l0ZSA9PSAiVHlsZXIgQ292ZSIsIHNlYXNvbiA9PSAicGVhayIpCgpzY2VuYXJpb18xID0gZnVsbF9kYXRhICU+JSAKICBtdXRhdGUocmVwX2N0bWF4ID0gZXN0XzEkbWVhbl9jdG1heCwKICAgICAgICAgcHJlZF93dCA9IHJlcF9jdG1heCAtIGNvbGxlY3Rpb25fdGVtcCwgCiAgICAgICAgIHd0X2RpZmYgPSBwcmVkX3d0IC0gd2FybWluZ190b2wpCgpnZ3Bsb3Qoc2NlbmFyaW9fMSwgYWVzKHggPSBsYXQsIHkgPSB3dF9kaWZmKSkgKyAKICBmYWNldF93cmFwKHNlYXNvbn4uLCBucm93ID0gMykgKyAKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIpICsgCiAgZ2VvbV9wb2ludCgpICsgCiAgbGFicyh4ID0gIkxhdGl0dWRlIiwgCiAgICAgICB5ID0gIlByZWRpY3RlZCAtIE9ic2VydmVkIFdUIikgKyAKICB0aGVtZV9tYXR0X2ZhY2V0cygpCgpsYXQubW9kZWwxID0gbG0oZGF0YSA9IHNjZW5hcmlvXzEsCiAgICAgICAgICAgICAgICB3dF9kaWZmIH4gbGF0KnNlYXNvbikKCmxhdF9zbG9wZV8xID0gZW1tZWFuczo6ZW10cmVuZHMobGF0Lm1vZGVsMSwgdmFyID0gImxhdCIsIHNwZWNzID0gInNlYXNvbiIpICU+JSAKICBhcy5kYXRhLmZyYW1lKCkgJT4lIAogIHNlbGVjdChzZWFzb24sIGxhdC50cmVuZCkKCnBlcmZvcm1hbmNlXzEgPSBzY2VuYXJpb18xICU+JSAKICBzZWxlY3Qoc2l0ZSwgbGF0LCBzZWFzb24sIHd0X2RpZmYpICU+JSAgCiAgZ3JvdXBfYnkoc2l0ZSwgc2Vhc29uLCBsYXQpICU+JSAKICBzdW1tYXJpc2UoIm1lYW5fZGlmZiIgPSBtZWFuKHd0X2RpZmYpLAogICAgICAgICAgICAiYWJzX2RpZmYiID0gYWJzKG1lYW5fZGlmZikpICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIG11dGF0ZSgiZmxhZyIgPSBpZl9lbHNlKGFic19kaWZmID49IDIsICJ5ZXMiLCAibm8iKSkgJT4lIAogIGZpbHRlcihmbGFnID09ICJ5ZXMiKSAlPiUgIAogIGdyb3VwX2J5KHNlYXNvbikgJT4lIAogIHN1bW1hcmlzZSgiYXZnX2RpZmYiID0gbWVhbihhYnNfZGlmZiksCiAgICAgICAgICAgICJuIiA9IG4oKSkgJT4lIAogIGlubmVyX2pvaW4obGF0X3Nsb3BlXzEsIGJ5ID0gInNlYXNvbiIpCmBgYAoKIyMjIFNjZW5hcmlvIDIgLSBTZWFzb25hbGx5IGludmFyaWFudCB0aGVybWFsIGxpbWl0cwoKTG9jYWwgYWRhcHRhdGlvbiBvZiB0aGVybWFsIGxpbWl0cyBpcyB3aWRlbHkgb2JzZXJ2ZWQgYWNyb3NzIGEgcmFuZ2Ugb2YgdGF4YSwgaW5jbHVkaW5nICpBY2FydGlhIHRvbnNhKi4gSW4gdGhlIHNlY29uZCBzY2VuYXJpbywgd2UgYWNjb3VudCBmb3IgdGhpcyBieSB1c2luZyBhdmVyYWdlIHRoZXJtYWwgbGltaXRzIGZyb20gdGhlIHBlYWsgc2Vhc29uIGZvciBlYWNoIHBvcHVsYXRpb24gaW4gdGhlIGVzdGltYXRlcyBvZiB3YXJtaW5nIHRvbGVyYW5jZSB0aHJvdWdob3V0IHRoZSB5ZWFyLiAKClVuc3VycHJpc2luZ2x5LCB0aGlzIGFwcHJvYWNoIGVsaW1pbmF0ZXMgdGhlIGxhdGl0dWRpbmFsIHRyZW5kLiBJbnN0ZWFkIHdlIHNlZSB0aGF0IHBlYWsgc2Vhc29uIGVzdGltYXRlcyB3ZXJlIGdlbmVyYWxseSBkZWNlbnQgcHJlZGljdG9ycyBvZiB3YXJtaW5nIHRvbGVyYW5jZSBkdXJpbmcgdGhlIGVhcmx5IHNlYXNvbiAoYWx0aG91Z2ggdGhlcmUgd2VyZSBzbGlnaHQgb3ZlcmVzdGltYXRlcyBpbiBzZXZlcmFsIHBvcHVsYXRpb25zKSwgYW5kIHNsaWdodGx5IHVuZGVyZXN0aW1hdGVkIHdhcm1pbmcgdG9sZXJhbmNlIGR1cmluZyB0aGUgbGF0ZSBzZWFzb24uCgpgYGB7cn0KZXN0XzIgPSBmdWxsX2RhdGEgJT4lIAogIGdyb3VwX2J5KHNpdGUsIHNlYXNvbikgJT4lIAogIHN1bW1hcmlzZSgibWVhbl9jdG1heCIgPSBtZWFuKGN0bWF4KSkgJT4lIAogIGZpbHRlcihzZWFzb24gPT0gInBlYWsiKSAlPiUgCiAgc2VsZWN0KHNpdGUsIG1lYW5fY3RtYXgpCgpzY2VuYXJpb18yID0gZnVsbF9kYXRhICU+JSAKICBpbm5lcl9qb2luKGVzdF8yLCBieSA9IGMoInNpdGUiKSkgJT4lIAogIG11dGF0ZShwcmVkX3d0ID0gbWVhbl9jdG1heCAtIGNvbGxlY3Rpb25fdGVtcCwgCiAgICAgICAgIHd0X2RpZmYgPSBwcmVkX3d0IC0gd2FybWluZ190b2wpCgpnZ3Bsb3Qoc2NlbmFyaW9fMiwgYWVzKHggPSBsYXQsIHkgPSB3dF9kaWZmKSkgKyAKICBmYWNldF93cmFwKHNlYXNvbn4uLCBucm93ID0gMykgKyAKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIpICsgCiAgZ2VvbV9wb2ludCgpICsgCiAgbGFicyh4ID0gIkxhdGl0dWRlIiwgCiAgICAgICB5ID0gIlByZWRpY3RlZCAtIE9ic2VydmVkIFdUIikgKyAKICB0aGVtZV9tYXR0X2ZhY2V0cygpCgpsYXQubW9kZWwyID0gbG0oZGF0YSA9IHNjZW5hcmlvXzIsCiAgICAgICAgICAgICAgICB3dF9kaWZmIH4gbGF0KnNlYXNvbikKCmxhdF9zbG9wZV8yID0gZW1tZWFuczo6ZW10cmVuZHMobGF0Lm1vZGVsMiwgdmFyID0gImxhdCIsIHNwZWNzID0gInNlYXNvbiIpICU+JSAKICBhcy5kYXRhLmZyYW1lKCkgJT4lIAogIHNlbGVjdChzZWFzb24sIGxhdC50cmVuZCkKCnBlcmZvcm1hbmNlXzIgPSBzY2VuYXJpb18yICU+JSAKICBzZWxlY3Qoc2l0ZSwgbGF0LCBzZWFzb24sIHd0X2RpZmYpICU+JSAgCiAgZ3JvdXBfYnkoc2l0ZSwgc2Vhc29uLCBsYXQpICU+JSAKICBzdW1tYXJpc2UoIm1lYW5fZGlmZiIgPSBtZWFuKHd0X2RpZmYpLAogICAgICAgICAgICAiYWJzX2RpZmYiID0gYWJzKG1lYW5fZGlmZikpICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIG11dGF0ZSgiZmxhZyIgPSBpZl9lbHNlKGFic19kaWZmID49IDIsICJ5ZXMiLCAibm8iKSkgJT4lIAogIGZpbHRlcihmbGFnID09ICJ5ZXMiKSAlPiUgIAogIGdyb3VwX2J5KHNlYXNvbikgJT4lIAogIHN1bW1hcmlzZSgiYXZnX2RpZmYiID0gbWVhbihhYnNfZGlmZiksCiAgICAgICAgICAgICJuIiA9IG4oKSkgJT4lICAKICBpbm5lcl9qb2luKGxhdF9zbG9wZV8yLCBieSA9IGMoInNlYXNvbiIpKQpgYGAKCiMjIyBTY2VuYXJpbyAzIC0gUG9wdWxhdGlvbiBzdWItc2FtcGxpbmcgCgpCb3RoIG9mIHRoZSBwcmV2aW91cyBhcHByb2FjaGVzIHRvIGVzdGltYXRpbmcgd2FybWluZyB0b2xlcmFuY2UgcmVzdWx0IGluIG92ZXJlc3RpbWF0ZXMgb2Ygd2FybWluZyB0b2xlcmFuY2UuIFRoZXNlIHJlZHVjdGl2ZSBtZXRob2RzIGluY3JlYXNlIHRoZSBmZWFzaWJpbGl0eSwgYnV0IGFyZSB1bmFibGUgdG8gYWNjb3VudCBmb3IgdGhlIGNvLW9jY3VyaW5nIHNoaWZ0cyBpbiBhbWJpZW50IHRlbXBlcmF0dXJlIGFuZCB0aGVybWFsIGxpbWl0cy4gQ29udGludW91cyBpbi1zaXR1IG1vbml0b3Jpbmcgb2YgdGhlcm1hbCBsaW1pdHMgaXMgaW1wcmFjdGljYWwsIGhvd2V2ZXIsIGVzcGVjaWFsbHkgZm9yIHNwZWNpZXMgd2l0aCBzbWFsbCBwb3B1YXRpb24gc2l6ZXMgYW5kL29yIHZlcnkgbGFyZ2UgcmFuZ2UgZGlzdHJpYnV0aW9ucy4gT25lIHBvdGVudGlhbCBjb21wcm9taXNlIHNvbHV0aW9uIGlzIHRvIHN1Yi1zYW1wbGUgcG9wdWxhdGlvbnMgYW5kIHVzZSBvYnNlcnZlZCBkYXRhIHRvIHByZWRpY3Qgc3BhdGlhbCBhbmQgc2Vhc29uYWwgY2hhbmdlcyBpbiB3YXJtaW5nIHRvbGVyYW5jZS4gCgpJbiB0aGlzIHRoaXJkIGFwcHJvYWNoLCB3ZSByYW5kb21seSBzZWxlY3RlZCBuaW5lIGNvbGxlY3Rpb25zLCBmaXQgYSBsaW5lYXIgbW9kZWwgb2YgQ1RtYXggfiBjb2xsZWN0aW9uIHRlbXBlcmF0dXJlLCBhbmQgdXNlZCB0aGlzIHJlZ3Jlc3Npb24gdG8gcHJlZGljdCB0aGVybWFsIGxpbWl0cyBhbmQgd2FybWluZyB0b2xlcmFuY2UgYWNyb3NzIHRoZSBmdWxsIHNldCBvZiBjb2xsZWN0aW9ucy4gVGhlc2UgcHJlZGljdGVkIHdhcm1pbmcgdG9sZXJhbmNlIHZhbHVlcyB3ZXJlIHRoZW4gY29tcGFyZWQgYWdhaW5zdCBvYnNlcnZlZCB3YXJtaW5nIHRvbGVyYW5jZSBhcyBiZWZvcmUuIFdlIHJlcGVhdGVkIHRoaXMgcHJvY2VzcyAxMDAgdGltZXMgKDEwMCByYW5kb20gc2V0cyBvZiA5IGNvbGxlY3Rpb25zKSB0byBleGFtaW5lIHRoZSBzZW5zaXRpdml0eSBvZiB0aGlzIGFwcHJvYWNoIHRoZSBwb3B1bGF0aW9ucyBhbmQgc2Vhc29ucyBjb2xsZWN0ZWQuIEluIGFkZGl0aW9uIHRvIHRoaXMgcmFuZG9tIGRhdGEsIHdlIGFsc28gaW5jbHVkZWQgYSBzY2VuYXJpbyB3aGVyZSBhbGwgc2Vhc29uYWwgY29sbGVjdGlvbnMgZnJvbSBGdC4gSGFtZXIsIFR5bGVyIENvdmUsIGFuZCBNaXJhbWljaGkgKHRoZSBsYXRpdHVkaW5hbCBleHRyZW1lcyBhbmQgYSBjZW50cmFsIHBvaW50KSB3ZXJlIHVzZWQgdG8gcHJlZGljdCB0aGVybWFsIGxpbWl0cy4gCgpgYGB7cn0KCnNjZW5hcmlvXzMgPSBkYXRhLmZyYW1lKCkKcGVyZm9ybWFuY2VfMyA9IGRhdGEuZnJhbWUoKQoKZm9yKGkgaW4gMToxMDApewogIAogIGVzdF8zID0gZnVsbF9kYXRhICU+JSAKICAgIGdyb3VwX2J5KHNpdGUsIHNlYXNvbiwgY29sbGVjdGlvbl90ZW1wKSAlPiUgCiAgICBzdW1tYXJpc2UoIm1lYW5fY3RtYXgiID0gbWVhbihjdG1heCksIC5ncm91cHMgPSAia2VlcCIpICU+JSAKICAgIHVuZ3JvdXAoKSAlPiUgCiAgICBmaWx0ZXIocm93X251bWJlcigpICVpbiUgc2FtcGxlKGMoMTptYXgocm93X251bWJlcigpKSksIHNpemUgPSA5LCByZXBsYWNlID0gRikpCiAgCiAgcmVwLm1vZGVsID0gbG0oZGF0YSA9IGVzdF8zLCBtZWFuX2N0bWF4IH4gY29sbGVjdGlvbl90ZW1wKQogIAogIHJlcF9kYXRhID0gZnVsbF9kYXRhICU+JSAKICAgIGdyb3VwX2J5KHNpdGUsIHNlYXNvbikgJT4lICAKICAgIG11dGF0ZShtZWFuX3d0ID0gbWVhbih3YXJtaW5nX3RvbCkpICU+JSAKICAgIHNlbGVjdChzaXRlLCBzZWFzb24sIGNvbGxlY3Rpb25fdGVtcCwgbGF0LCBtZWFuX3d0KSAlPiUgCiAgICB1bmdyb3VwKCkgJT4lIAogICAgZGlzdGluY3QoKSAlPiUgIAogICAgbXV0YXRlKHByZWRfY3RtYXggPSBwcmVkaWN0KHJlcC5tb2RlbCwgbmV3ZGF0YSA9IC4pLAogICAgICAgICAgIHByZWRfd3QgPSBwcmVkX2N0bWF4IC0gY29sbGVjdGlvbl90ZW1wLAogICAgICAgICAgIHd0X2RpZmYgPSBwcmVkX3d0IC0gbWVhbl93dCwKICAgICAgICAgICBydW4gPSBpLAogICAgICAgICAgIGdyb3VwID0gInJhbmRvbSIpCiAgCiAgc2NlbmFyaW9fMyA9IGJpbmRfcm93cyhzY2VuYXJpb18zLCByZXBfZGF0YSkKICAKICBsYXQubW9kZWwzID0gbG0oZGF0YSA9IHNjZW5hcmlvXzMsCiAgICAgICAgICAgICAgICAgIHd0X2RpZmYgfiBsYXQqc2Vhc29uKQogIAogIGxhdF9zbG9wZV8zID0gZW1tZWFuczo6ZW10cmVuZHMobGF0Lm1vZGVsMywgdmFyID0gImxhdCIsIHNwZWNzID0gInNlYXNvbiIpICU+JSAKICAgIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAgICBzZWxlY3Qoc2Vhc29uLCBsYXQudHJlbmQpCiAgCiAgcmVwX3BlcmZvcm1hbmNlID0gc2NlbmFyaW9fMyAlPiUgCiAgICBzZWxlY3Qoc2l0ZSwgbGF0LCBzZWFzb24sIHd0X2RpZmYpICU+JSAgCiAgICBncm91cF9ieShzaXRlLCBzZWFzb24sIGxhdCkgJT4lIAogICAgc3VtbWFyaXNlKCJtZWFuX2RpZmYiID0gbWVhbih3dF9kaWZmKSwKICAgICAgICAgICAgICAiYWJzX2RpZmYiID0gYWJzKG1lYW5fZGlmZiksIAogICAgICAgICAgICAgIC5ncm91cHMgPSAia2VlcCIpICU+JSAKICAgIHVuZ3JvdXAoKSAlPiUgCiAgICBtdXRhdGUoImZsYWciID0gaWZfZWxzZShhYnNfZGlmZiA+PSAyLCAieWVzIiwgIm5vIikpICU+JSAKICAgIGZpbHRlcihmbGFnID09ICJ5ZXMiKSAlPiUgIAogICAgZ3JvdXBfYnkoc2Vhc29uKSAlPiUgCiAgICBzdW1tYXJpc2UoImF2Z19kaWZmIiA9IG1lYW4oYWJzX2RpZmYpLAogICAgICAgICAgICAgICJuIiA9IG4oKSwKICAgICAgICAgICAgICAuZ3JvdXBzID0gImtlZXAiKSAlPiUgIAogICAgaW5uZXJfam9pbihsYXRfc2xvcGVfMywgYnkgPSBjKCJzZWFzb24iKSkKICAKICBwZXJmb3JtYW5jZV8zID0gYmluZF9yb3dzKHBlcmZvcm1hbmNlXzMsIHJlcF9wZXJmb3JtYW5jZSkKICAKfQoKZ29sZF9zdGFuZCA9IGZ1bGxfZGF0YSAlPiUgCiAgZ3JvdXBfYnkoc2l0ZSwgc2Vhc29uLCBjb2xsZWN0aW9uX3RlbXApICU+JSAKICBzdW1tYXJpc2UoIm1lYW5fY3RtYXgiID0gbWVhbihjdG1heCksIC5ncm91cHMgPSAia2VlcCIpICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIGZpbHRlcihzaXRlICVpbiUgYygiRnQuIEhhbWVyIiwgIlR5bGVyIENvdmUiLCAiTWlyYW1pY2hpIikpCgpnb2xkLm1vZGVsID0gbG0oZGF0YSA9IGdvbGRfc3RhbmQsIG1lYW5fY3RtYXggfiBjb2xsZWN0aW9uX3RlbXApCgpnb2xkX2RhdGEgPSBmdWxsX2RhdGEgJT4lIAogIGdyb3VwX2J5KHNpdGUsIHNlYXNvbikgJT4lICAKICBtdXRhdGUobWVhbl93dCA9IG1lYW4od2FybWluZ190b2wpKSAlPiUgCiAgc2VsZWN0KHNpdGUsIHNlYXNvbiwgY29sbGVjdGlvbl90ZW1wLCBsYXQsIG1lYW5fd3QpICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIGRpc3RpbmN0KCkgJT4lICAKICBtdXRhdGUocHJlZF9jdG1heCA9IHByZWRpY3QoZ29sZC5tb2RlbCwgbmV3ZGF0YSA9IC4pLAogICAgICAgICBwcmVkX3d0ID0gcHJlZF9jdG1heCAtIGNvbGxlY3Rpb25fdGVtcCwKICAgICAgICAgd3RfZGlmZiA9IHByZWRfd3QgLSBtZWFuX3d0LAogICAgICAgICBydW4gPSBpICsgMSwKICAgICAgICAgZ3JvdXAgPSAiZ29sZCIpCgpnb2xkLm1vZGVsID0gbG0oZGF0YSA9IGdvbGRfZGF0YSwKICAgICAgICAgICAgICAgIHd0X2RpZmYgfiBsYXQqc2Vhc29uKQoKZ29sZF9zbG9wZSA9IGVtbWVhbnM6OmVtdHJlbmRzKGdvbGQubW9kZWwsIHZhciA9ICJsYXQiLCBzcGVjcyA9ICJzZWFzb24iKSAlPiUgCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICBzZWxlY3Qoc2Vhc29uLCBsYXQudHJlbmQpCgpnb2xkX3BlcmZvcm1hbmNlID0gZ29sZF9kYXRhICU+JSAKICBzZWxlY3Qoc2l0ZSwgbGF0LCBzZWFzb24sIHd0X2RpZmYpICU+JSAgCiAgZ3JvdXBfYnkoc2l0ZSwgc2Vhc29uLCBsYXQpICU+JSAKICBzdW1tYXJpc2UoIm1lYW5fZGlmZiIgPSBtZWFuKHd0X2RpZmYpLAogICAgICAgICAgICAiYWJzX2RpZmYiID0gYWJzKG1lYW5fZGlmZiksIAogICAgICAgICAgICAuZ3JvdXBzID0gImtlZXAiKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBtdXRhdGUoImZsYWciID0gaWZfZWxzZShhYnNfZGlmZiA+PSAyLCAieWVzIiwgIm5vIikpICU+JSAKICBmaWx0ZXIoZmxhZyA9PSAieWVzIikgJT4lICAKICBncm91cF9ieShzZWFzb24pICU+JSAKICBzdW1tYXJpc2UoImF2Z19kaWZmIiA9IG1lYW4oYWJzX2RpZmYpLAogICAgICAgICAgICAibiIgPSBuKCksCiAgICAgICAgICAgIC5ncm91cHMgPSAia2VlcCIpICU+JSAgCiAgaW5uZXJfam9pbihnb2xkX3Nsb3BlLCBieSA9IGMoInNlYXNvbiIpKQoKc2NlbmFyaW9fMyA9IGJpbmRfcm93cyhzY2VuYXJpb18zLCBnb2xkX2RhdGEpCgpwZXJmb3JtYW5jZV8zX3N1bSA9IHBlcmZvcm1hbmNlXzMgJT4lICAKICBncm91cF9ieShzZWFzb24pICU+JSAgCiAgc3VtbWFyaXNlKCJhdmdfZGlmZiIgPSBtZWFuKGF2Z19kaWZmKSwKICAgICAgICAgICAgIm4iID0gbWVhbihuKSwKICAgICAgICAgICAgImxhdC50cmVuZCIgPSBtZWFuKGxhdC50cmVuZCkpCgpnZ3Bsb3Qoc2NlbmFyaW9fMywgYWVzKHggPSBsYXQsIHkgPSB3dF9kaWZmLCBjb2xvdXIgPSBncm91cCwgZ3JvdXAgPSBydW4pKSArIAogIGZhY2V0X3dyYXAoc2Vhc29ufi4sIG5yb3cgPSAzKSArIAogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDApICsgCiAgZ2VvbV9zbW9vdGgoYWVzKGNvbG91ciA9IGdyb3VwKSwgCiAgICAgICAgICAgICAgbWV0aG9kID0gImxtIiwgc2UgPSBGKSArIAogIGdlb21fcG9pbnQoKSArIAogIGxhYnMoeCA9ICJMYXRpdHVkZSIsIAogICAgICAgeSA9ICJQcmVkaWN0ZWQgLSBPYnNlcnZlZCBXVCIpICsgCiAgdGhlbWVfbWF0dF9mYWNldHMoKQoKYGBgCgpgYGB7cn0Ka25pdHI6OmthYmxlKHBlcmZvcm1hbmNlXzEsIGNhcHRpb24gPSAiU2NlbmFyaW8gMSIpCgprbml0cjo6a2FibGUocGVyZm9ybWFuY2VfMiwgY2FwdGlvbiA9ICJTY2VuYXJpbyAyIikKCmtuaXRyOjprYWJsZShwZXJmb3JtYW5jZV8zX3N1bSwgY2FwdGlvbiA9ICJTY2VuYXJpbyAzIikKCmtuaXRyOjprYWJsZShnb2xkX3BlcmZvcm1hbmNlLCBjYXB0aW9uID0gImBHb2xkYCBTdGFuZGFyZCIpCmBgYAoKYGBge3J9CmJlc3QgPSBiaW5kX3Jvd3MoCiAgbXV0YXRlKHBlcmZvcm1hbmNlXzEsICJzY2VuYXJpbyIgPSAib25lIiksCiAgbXV0YXRlKHBlcmZvcm1hbmNlXzIsICJzY2VuYXJpbyIgPSAidHdvIiksCiAgbXV0YXRlKHBlcmZvcm1hbmNlXzNfc3VtLCAic2NlbmFyaW8iID0gInRocmVlIiksCiAgbXV0YXRlKGdvbGRfcGVyZm9ybWFuY2UsICJzY2VuYXJpbyIgPSAiZ29sZCIpKSAlPiUgCiAgZ3JvdXBfYnkoc2Vhc29uKSAlPiUgIAogIGZpbHRlcihhYnMobGF0LnRyZW5kKSA9PSBtaW4oYWJzKGxhdC50cmVuZCkpKQojZmlsdGVyKGF2Z19kaWZmID09IG1pbihhdmdfZGlmZikpCmBgYAoKCiMjIE5leHQgU3RlcHMKCkFmdGVyIHBoZW5vdHlwaW5nLCBlYWNoIGluZGl2aWR1YWwgd2FzIHByZXNlcnZlZCBpbiA5NSUgZXRoYW5vbC4gSW5kaXZpZHVhbCBETkEgbGlicmFyaWVzIHdpbGwgYmUgcHJlcGFyZWQgdXNpbmcgVHdpc3QgQmlvIDk2LXBsZXggcHJlcCBraXRzLCB0aGVuIHNlcXVlbmNlZCBvbiBhbiBJbGx1bWluYSBOb3ZhU2VxIFggUGx1cy4gVXNpbmcgdGhlIGxvdy1jb3ZlcmFnZSB3aG9sZSBnZW5vbWUgc2VxdWVuY2VzLCB3ZSB3aWxsIGV4YW1pbmUgc2Vhc29uYWwgcGF0dGVybnMgaW4gYWxsZWxlIGZyZXF1ZW5jeSBjaGFuZ2UsIGFuZCBjb21wYXJlIHRoZXNlIGZpbmUgc2NhbGUgdGVtcG9yYWwgcGF0dGVybnMgd2l0aCB0aGUgbGFyZ2VyIGxhdGl0dWRpbmFsIHBhdHRlcm5zIGluIGFsbGVsZSBmcmVxdWVuY3kgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhlIHNhbWUgYWxsZWxlcyBkcml2aW5nIHJhcGlkIHNlYXNvbmFsIGFkYXB0YXRpb24gYXJlIGluIHBsYXkgb3ZlciBsYXJnZXIgc3BhdGlhbCAoYW5kIGxvbmdlciB0ZW1wb3JhbCkgc2NhbGVzLgoKIyMgTWlzYy4gRGV0YWlscwoKYGBge3IgdGVtcC1yZWNvcmQtcGxvdCwgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9Nn0KZ2dwbG90KHRlbXBfcmVjb3JkLCBhZXMoeCA9IG1pbnV0ZV9wYXNzZWQsIHkgPSB0ZW1wX0MsIGdyb3VwID0gZmFjdG9yKHJ1bikpKSArIAogIGdlb21fYWJsaW5lKHNsb3BlID0gMC4zLCBpbnRlcmNlcHQgPSBtZWFuKHRlbXBfcmVjb3JkW3RlbXBfcmVjb3JkJG1pbnV0ZV9pbnRlcnZhbCA9PSAwLCA4XSkpICsgCiAgZ2VvbV9hYmxpbmUoc2xvcGUgPSAwLjEsIGludGVyY2VwdCA9IG1lYW4odGVtcF9yZWNvcmRbdGVtcF9yZWNvcmQkbWludXRlX2ludGVydmFsID09IDAsIDhdKSkgKyAKICBnZW9tX2xpbmUobGluZXdpZHRoID0gMC4yLCBhbHBoYSA9IDAuOCkgKyAKICBnZW9tX3BvaW50KGRhdGEgPSBmdWxsX2RhdGEsIAogICAgICAgICAgICAgYWVzKHggPSB0aW1lLCB5ID0gY3RtYXggKyAwLjQpLAogICAgICAgICAgICAgc2l6ZSA9IDIsCiAgICAgICAgICAgICBzaGFwZSA9IDI1KSArCiAgbGFicyh4ID0gIlRpbWUgcGFzc2VkIChtaW51dGVzKSIsCiAgICAgICB5ID0gIlRlbXBlcmF0dXJlIChkZWdyZWVzIEMpIiwKICAgICAgIGZpbGwgPSAiVHJpYWwgTnVtYmVyIikgKyAKICBndWlkZXMoY29sb3VyID0gIm5vbmUiKSArIAogIHRoZW1lX21hdHQoYmFzZV9zaXplID0gMTYpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKYGBgCgpgYGB7ciByYW1wLXJlY29yZC1wbG90LCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD02fQpyYW1wX3JlY29yZDIgPSByYW1wX3JlY29yZCAlPiUgCiAgZ3JvdXBfYnkocnVuLCBtaW51dGVfaW50ZXJ2YWwpICU+JSAKICBzdW1tYXJpc2UobWVhbl9yYW1wID0gbWVhbihyYW1wX3Blcl9taW51dGUpKSAlPiUgCiAgdW5ncm91cCgpCgpnZ3Bsb3QocmFtcF9yZWNvcmQyLCBhZXMoeCA9IG1pbnV0ZV9pbnRlcnZhbCwgeSA9IG1lYW5fcmFtcCkpICsgCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMC4zKSArIAogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAuMSkgKyAKICAjZ2VvbV9wb2ludCgpICsgCiAgZ2VvbV9oZXgoYmlucyA9IDMwKSArIAogIHlsaW0oMCwgMC4zNSkgKyAKICBsYWJzKHkgPSAiUmFtcCBSYXRlIChkZWcuIEMgLyBtaW4uKSIsCiAgICAgICB4ID0gIlRpbWUgaW50byBydW4gKG1pbnV0ZSkiKSArIAogIHRoZW1lX21hdHQoYmFzZV9zaXplID0gMTYpIApgYGAKCmBgYHtyIHJlcC1jb21wLCBmaWcuaGVpZ2h0PTEyLCBmaWcud2lkdGg9OH0KZnVsbF9kYXRhICU+JSAKICBkcm9wX25hKHJlcGxpY2F0ZSkgJT4lICAKICBnZ3Bsb3QoYWVzKHggPSBmYWN0b3IocmVwbGljYXRlKSwgeSA9IGN0bWF4LCBncm91cCA9IHNpdGUpKSArIAogIGZhY2V0X2dyaWQoc2l0ZX5zZWFzb24sIHNjYWxlcyA9ICJmcmVlX3kiKSArIAogIGdlb21fcG9pbnQocG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXIod2lkdGggPSAwLjEsIGhlaWdodCA9IDApLAogICAgICAgICAgICAgYWxwaGEgPSAwLjQsCiAgICAgICAgICAgICBjb2xvdXIgPSAiZ3JleTMwIikgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBjb2xvdXIgPSAiYmxhY2siKSArIAogIGxhYnMoeCA9ICJSZXBsaWNhdGUiLCAKICAgICAgIHkgPSAiQ1RtYXgiKSArIAogIHRoZW1lX21hdHRfZmFjZXRzKCkKYGBgCgpgYGB7ciBudW0tZ2Vucy1wbG90LCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9N30KZ2dwbG90KGhhbGRhbmVzLCBhZXMoeCA9IGxhdCwgeSA9IGdlbnMsIGNvbG91ciA9IHNpdGUsIHNoYXBlID0gc2Vhc29uKSkgKyAKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxKSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDUpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh4ID0gIkxhdGl0dWRlIiwgCiAgICAgICB5ID0gIkdlbmVyYXRpb25zIGJldHdlZW4gXG5jb2xsZWN0aW9ucyIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKGZyb20gPSAwLCB0byA9IDIxLCBieSA9IDUpKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCmBgYAoKYGBge3IgcmFuay1zaW1zLCBmaWcud2lkdGg9MTgsIGZpZy5oZWlnaHQ9OH0Kb2JzX3JhbmtzID0gZ2dwbG90KGZ1bGxfZGF0YSwgYWVzKHggPSByYW5rKSkgKyAKICBmYWNldF93cmFwKHR1YmV+LikgKyAKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDEpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGMoMiw0LDYsOCwxMCkpICsgCiAgZ2d0aXRsZSgiT2JzZXJ2YXRpb24iKSArIAogIHRoZW1lX21hdHRfZmFjZXRzKCkKCnNpbV9kYXRhID0gZGF0YS5mcmFtZSgpCmZvcihpIGluIDE6bWF4KGZ1bGxfZGF0YSRydW4pKXsKICByZXBfZGF0YSA9IGRhdGEuZnJhbWUoInR1YmUiID0gc2FtcGxlKGMoMToxMCksIHNpemUgPSAxMCwgcmVwbGFjZSA9IEYpLCAKICAgICAgICAgICAgICAgICAgICAgICAgInJhbmsiID0gYygxOjEwKSwKICAgICAgICAgICAgICAgICAgICAgICAgInJlcCIgPSBpKSAlPiUgCiAgICBhcnJhbmdlKHR1YmUpCiAgCiAgc2ltX2RhdGEgPSBiaW5kX3Jvd3Moc2ltX2RhdGEsIHJlcF9kYXRhKQogIAp9CgpzaW1fcmFua3MgPSBnZ3Bsb3Qoc2ltX2RhdGEsIGFlcyh4ID0gcmFuaykpICsgCiAgZmFjZXRfd3JhcCh0dWJlfi4pICsgCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAxKSArIAogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBjKDIsNCw2LDgsMTApKSArIAogIGdndGl0bGUoIlNpbXVsYXRpb24iKSArIAogIHRoZW1lX21hdHRfZmFjZXRzKCkKCgpnZ2FycmFuZ2Uob2JzX3JhbmtzLCBzaW1fcmFua3MpCmBgYAoK